web-dev-qa-db-ja.com

バッククォート置換にスペースを含むファイル名

with spaceのように名前にスペースを含むファイルがあるとします。 cmdが 'with space'を引数として受け入れるために、以下のスニペットでlsは何を出力する必要がありますか?

$ ls `cmd`

ls `echo 'with space'`を試しました。 lsに渡される引数は、'withspace'です。バックスラッシュを使用してスペースをエスケープしようとしても機能しません。 ls "`cmd`"を使用すると機能することがわかります。ただし、スペースを含む可能性のあるlsに引数として複数のファイルを渡したい場合、これは機能しません。

コマンド置換に関するマニュアルもまばらに見えます。 https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html

より一般的には、バッククォート置換を使用して別のコマンドで使用するために置換できるファイルのリストを出力する場合、cmdが従う出力形式は何ですか?

4

ls "`cmd`"を使用すると機能することがわかります。ただし、スペースが含まれている可能性のあるlsの引数として複数のファイルを渡したい場合、これは機能しません。

そのとおりです。これは、コマンドを変数に格納する場合と同じ問題です(ここで説明します 例:ここ )、実際にはうまく実行できません。頭に浮かぶオプションは次のとおりです。

  • cmdにファイル名のNUL区切りリストを出力させてから、xargs -0にパイプして別のコマンドに渡します
  • IFSをファイル名に表示されない文字に設定し、cmdにファイルのリストを出力させます。
  • cmdに、シェル用に適切に引用されたファイル名を出力させてから、evalを実行します。

そのようです:

$ touch "with space" "another space"
$ printf "%s\0" "with space" "another space" | xargs -0 ls -i
1705749 another space  1705230 with space
$ set -f; IFS=%; ls -i $(echo "with space%another space")
1705749 another space  1705230 with space
$ eval ls -i "$(echo '"with space" "another space"')"
1705749 another space  1705230 with space

または、cmdをそれに置き換えることができる場合は、find -exec ...を使用します。

5
ilkkachu