play
ファイル(スペースを含む)を含むフォルダがありますdamn file
。find
出力を使用してパイプする場合tar
:
find play/ -name 'damn*' | tar cf archive.tar -T -
完璧に動作します。これがうまくいくのはなぜですか?出力にfind
問題を引き起こす可能性のあるスペースが含まれていますtar
。このコマンドを使用するとき:
tar cf archive.tar $(find play/ -name 'damn*')
Bash は次のエラーを表示します。
tar: play/damn: Cannot stat: No such file or directory
tar: file: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
混乱しています。最初の例が機能するのはなぜですか?
答え1
2番目の例では、コマンド置換の出力をトークン化するシェルによって改行文字が削除されます。改行文字はデフォルトで含まれるため、IFS
フィールド自体の一部ではなくフィールド区切り文字と見なされます。最初の例では、入力がシェルではなくパイプから出るため、シェルはトークン化を実行できません。
二重引用符で囲まれたコマンド置換("$(find ... )"
)は単語の区切りが発生するのを防ぎますが、find
内部コマンド置換はほとんど常に発生します。悪いそんな思いはしないでください。セキュリティを最大化するには、UnixツールのGNUバージョンにアクセスできる限り、空の区切り文字オプションを使用する必要があります。
find dir/ -name '...' -print0 | tar cf foo.tar --null --no-recursion -T -