シェルから変数を引用するための答えをここで読みました。基本的にこれは私が実行するものです。
for f in "$(tmsu files)"; do echo "${f}"; done
これは予想される結果です:ファイルのリスト。しかし、私はそれらが1つの文字列として現れると確信しています。少し読んだ後、これがzsh-ismであることに気づきました。これは、ほとんどのシェルとは異なる方法で分割を処理します。
bash
だから私は同じコマンドを実行して実行しました。リストが分割されると思いましたが、残念ながら正確に同じ結果。だから今は本当に混乱しています。
- Bashが期待どおりに実行されないのはなぜですか?
- zsh分割線を作成する方法は?
私は(zsh)を試しましたが成功しなかったfor f in "$(tmsu files)"; do echo "${=f}"; done
ので
for f in "$(=tmsu files)"; do echo "${f}"; done
、分割方法を誤解したようですzsh
。
さらに悪いことは、ある時点で私が望むように正確に動作するようにしましたが、どうしたのか覚えていないということです。
ベストアンサー1
for f in "$(tmsu files)"; do echo "${f}"; done
これはzsh-ismよりも悪い習慣です。二重引用符は、拡張結果を単一の文字列として保持するようにシェルに指示します。ほとんどの場合、これはあなたが望むものです。たとえば、次のような場合があります。
filename="foo bar"
ls "$filename"
2つの引数ls
の合計ではなく単一の引数でファイル名を取得しようとしています。 (これらは別のファイル名になります。)これで、コマンド置換を使用しているという事実はこれを変更しません。この場合、引用が問題を解決できないことは正しいですが、この構成は最初は厄介です。 (もちろん、POSIXシェルにはzshに独自のツールがあります)。foo
bar
次のファイルのリストを検討してください。
hello.txt
some silly name with spaces.txt
を使用すると、2つで"$(output filenames)"
はなく1つの文字列が提供されます。
を使用すると、$(output filenames)
2つではなく6つの文字列が提供されます。
IFS
後者が改行文字に分割され、2つのファイル名を提供するように改行文字のみを設定することでこの問題を解決できます。ただし、これは面倒でグローバルな影響を与え、set -f
ファイル名が変更されないようにするには、まだワイルドカードを無効にする必要がありますfunny * name.txt
。
(これまでは、変数拡張を分割しなくても引用符なしのコマンド置換結果を分割する点で、デフォルトではzshと同じですが、デフォルトでは結果をワイルドカードとして表示しません。)
違いを見ることができない理由は、echo
取得したすべての引数を単一のスペースで連結して印刷するためです。したがって、まったく同じ出力を生成しますecho foo bar
。echo "foo bar"
代わりに、次のようなものを使用すると、printf "<%s>\n" ...
パラメータの境界をより明確に表示できます。
$ printf "<%s>\n" foo bar
<foo>
<bar>
$ printf "<%s>\n" "foo bar"
<foo bar>
また見なさい:
- 噴射Gregのwikiから
- 「for」のある行を読んでみてはいかがでしょうか?
- ファイルの行を繰り返す方法は?(「ファイル行」と呼ばれていますが、コマンド置換にその内容やその他の内容があるかどうかは重要ではありません
cat
。) 常にそうであるように、次のようになります。 - スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?