なぜエラーが発生するのかわかりません。実際のコードをシミュレートしたテストコードです。ラッパーを作成しfind
、すべてのパラメータを受け入れたいので、各パラメータを一重引用符で囲みました。
#!/bin/bash
function find2 {
ARGS="/usr/bin/find"
while [[ $# -gt 0 ]]; do
ARGS="$ARGS '$1'"
shift
done
echo CALLING: $ARGS
$ARGS
}
find2 /tmp/test -name "hello.c" # THIS IS THE DESIRED IMPLEMENTATION (doesn't work)
find '/tmp/test' '-name' 'hello.c' # THIS IS FOR DEBUGGING (works)
「find2」が動作したいのですが、動作しません。次の結果が表示されます。
CALLING: /usr/bin/find '/tmp/test' '-name' 'hello.c'
/usr/bin/find: `\'/tmp/test\'': No such file or directory
/usr/bin/find: `\'-name\'': No such file or directory
/usr/bin/find: `\'hello.c\'': No such file or directory
ただし、(find2によって生成された)まったく同じコマンドを直接使用すると、うまく機能します。
/tmp/test/hello.c
何が起こったのかわかりません。
ベストアンサー1
(Bashから)値の配列に変更できます。
find2() {
ARGS="/usr/bin/find"
ARGS+=( "$@" )
echo CALLING: "${ARGS[@]}"
"${ARGS[@]}"
}
find2 /tmp/test -name "hello.c"
しかし、これはうまくいき、とても簡単です。
find2() {
ARGS=( "/usr/bin/find" "$@" )
echo CALLING: "${ARGS[@]}"
"${ARGS[@]}"
}
find2 /tmp/test -name "hello.c"
もちろん、直接的な方法も可能です(関数を持つすべてのシェルで):
find2() { /usr/bin/find "$@"; }
find2 /tmp/test -name "hello.c"
元のコードが失敗するのはなぜですか?
コードが実行するアクションを「確認」するには、set -x 以上を使用できます。次のようにechoをprintfに置き換えます。
find2() {
ARGS="/usr/bin/find"
ARGS+=( "$@" )
printf '<%s> ' CALLING: "${ARGS[@]}"; echo
"${ARGS[@]}"
}
find2 /tmp/test -name "hello.c"
実行すると、次のように表示されます。
$ ./script.sh
<CALLING:> </usr/bin/find> </tmp/test> <-name> <hello.c>
各パラメータは別々の要素です(<>位置に注意してください)。
ただし、ソースコード(printfの追加)では、次のことを行います。
function find2 {
ARGS="/usr/bin/find"
while [[ $# -gt 0 ]]; do
ARGS="$ARGS '$1'"
shift
done
printf '<%s> ' CALLING: "${ARGS[@]}"; echo
$ARGS
}
find2 /tmp/test -name "hello.c"
実行すると、次のようになります。
$ ./script.sh
<CALLING:> </usr/bin/find '/tmp/test' '-name' 'hello.c'>
すべての値は個々のパラメータではなく1つの長いテキスト行です(<>配置に注意してください)。