Bashシェルでは、次の点を考慮してください。
$ x="-name 'foo bar'"
$ find $x
find: paths must precede expression: `bar''
$ find -name 'foo bar'
./foo bar
そのように動作さ$x
せるには、何を入れることができますか?find $x
find -name 'foo bar'
答え1
単一の文字列に別の内容(-name
および)を入れないでください。foo bar
代わりに配列を使用してください。
args=( -name 'foo bar' )
find . "${args[@]}"
配列変数拡張の引用符は、各要素が個別に引用されることを保証します。これにより、これが単一のパラメータであることがfoo bar
保証されます。
位置パラメータも使用できます。
set -- -name 'foo bar'
find . "$@"
繰り返しますが、引用は"$@"
不可欠です。
-name 'foo bar'
変数を入れて引用符なしで使用すると、find
シェルは値をスペース、タブ、および改行で除算します。これはfind
、ユーティリティがパラメータとを取得したこと-name
を'foo
意味しますbar'
。bar'
パラメータがわからないのでfind
文句を言います。
文字列にワイルドカードパターン(たとえば)がある場合、-name '*.txt'
シェルはそれを-name
合計に分割'*.txt'
し、'*.txt'
現在のディレクトリで名前を拡張するためのワイルドカードパターンとして使用されます。
答え2
注:Linuxはfind構文をサポートしていますが、普遍的ではありません。たとえば、ほとんどのBSD派生では機能しませんが、次のような結果が得られます。
bash-3.2$ find -name 'foo bar'
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
問題は場所ではなく、引用と引用の解釈です。コードを次のように置き換えることができます。
x='foo bar'
find -name "$x"
あるいは、evalを試してみることもできます。
x="-name 'foo bar'"
eval "find $x"
少なくとも私のシステムでは、次のような結果が発生します。
bash-5.1$ x="-name 'foo bar'"
bash-5.1$ eval "find $x"
./foo bar
私はこれが望む結果だと信じています。