
コマンド置換がスペースで区切られた一重引用符POSIXパスのリストを渡すにはどうすればよいですか?
command1 $(command2)
command1 '/path/to/file 1' '/path/to/file 2' '/path/to/file 3'
拡張機能をどのように追跡しますか?
答え1
を使用して、どのコマンドが実行されているかを正確に確認できますset -x
。やや愚かな例:
$ echo $(echo "foo 'bar baz' taz\\ jaz")
foo 'bar baz' taz\ jaz
減らす:
++ echo 'foo '\''bar baz'\'' taz\ jaz'
+ echo foo ''\''bar' 'baz'\''' 'taz\' jaz
foo 'bar baz' taz\ jaz
すべてのエスケープのため読書が少し難しいです。たとえば、2番目の単語は次のようになります。
''
何もないことになる。\'
一重引用符('
)で'bar'
~になるbar
したがって、パラメータはに渡されます'bar
。次のようにこれを確認できます(Data::Dumpがインストールされていると仮定しますが、残念ながらデフォルトではありません)。$(echo…
これはPerl行にそのままコピーされました。
$ perl -MData::Dump=pp -E 'pp @ARGV' $(echo "foo 'bar baz' taz\\ jaz")
("foo", "'bar", "baz'", "taz\\", "jaz")
ここで何が起こるのかは、bashが$IFS
引数解析ではなく単語分割(offベース)を実行することです。したがって、残念ながら、それを使用し、eval
それに伴うすべてのリスクを処理する必要があるかもしれません。
$ eval "echo $(echo "foo 'bar baz' taz\\ jaz")"
foo bar baz taz jaz
(また、コマンドがNULで区切られた名前のリストで出力を生成することができる場合は、次のようにします。シンプル取り扱いの使用xargs -0
、さらに完全に安全です)。
答え2
わかりやすい形式のファイルリストがあることはほとんどありませんxargs
。だから走る
command1 | xargs command2
一部のUNIXバリアントでは、出力が非常に大きい場合、command1
コマンドラインの長さの制限により、すべてのファイル名で実行されません。command2
使用の欠点は、xargs
エラーを正しく報告するのではなく、コマンドを複数回実行することです。getconf ARG_MAX
以下を使用して、コマンドラインの長さの制限を確認できます。
答え3
次のようにしてみてください。 -
path1="/etc/passwd"
path2="/var/log/secure"
[root@localhost base_filters]# ls -l "$path1" "$path2"
-rw-r--r--. 1 root root 1876 Mar 10 22:15 /etc/passwd
-rw-------. 1 root root 2408 Apr 5 23:09 /var/log/secure
答え4
スペースがスクリプトに影響しないように、IFS変数を使用してみてください。 IFSを変数に保存し、スクリプトが完了したらIFSを復元します。