私はシェルに関して比較的基本的なポイントを見落としているかもしれません。 lsコマンドからの出力は、デフォルトでは出力を改行で区切りますが、シェルは出力を1行で表示します。
誰か私にこれを説明できますか?出力は単にスペースで区切られていると常に想定していましたが、改行で区切られた出力が表示されたので、出力が別の行に表示されることを期待しました。
例:
cpoweradm@debian:~/lpi103-4$ ls text*
text1 text2 text3
odは、出力が改行で区切られていることを示します。
cpoweradm@debian:~/lpi103-4$ ls text* | od -c
0000000 t e x t 1 \n t e x t 2 \n t e x t
0000020 3 \n
0000022
改行が存在する場合、出力が次のように表示されないのはなぜですか。
text1
text2
text3
出力をパイプすると、ls
の動作が異なります。
この事実は 情報ドキュメント に隠されています:
標準出力が端末の場合、出力は列(垂直方向にソート)になり、制御文字は疑問符として出力されます。それ以外の場合、出力は1行に1つずつリストされ、制御文字はそのまま出力されます。
それを証明するには、実行してみてください
ls
その後
ls | less
これは、出力がパイプされているかリダイレクトされているかに関係なく、出力が1行あたり1つのファイルであることを保証したい場合は、次を実行する必要があることを意味します。
ls -1
(-1
はナンバーワンです)
または、強制的にls | less
を実行して列に出力します
ls -C
(-C
は大文字のC)です
あなたの発見は、ls
の出力を解析することが常に悪い考えである主な理由を強調しています。 完全な説明 については、Gregのwikiを参照してください。
問題を逆に考えてください。 lsが出力の間に改行を出力する場合と出力しない場合があることに気付きました。スクリプトで使用する場合、または-1
フラグで強制された場合に使用します。各ファイルの最後に1つの改行。何があるか各改行が新しいファイル名を表すという保証はありません。実際、ファイル名自体に改行が含まれている場合、lsの出力は絶対に解析できなくなります。次のファイル名を検討してください。
file1
file2\nfile3
file4
その中にディレクトリをls -1
すると、次のようになります。
file1
file2
file3
file4
4つのファイルがあると自然に想定しませんか? lsの出力を解析するスクリプトも同様です。実際には3つのファイルがあり、そのうちの1つはトリッキーな名前ですが、lsの出力からそれを理解することはできません。*
* -l
フラグを使用していて、出力が中断されていることに気付いた場合を除いて、スクリプトは依然として窒息していました。