パイプされたlsはls -1と同じですか?


19

lsいくつかの列に出力を返しますが、私が試したディレクトリでls|catは、バイトが同じ出力を返しますls -1。それでも、私はls -1答えの中でパイプされたように見えls -1|wc -lます。好む理由はありls -1ますか?...|catの出力が変わるのはなぜlsですか?


1
あなたがそれらのいくつかの回を数えますので、ファイル名があなたの代わりにposixly行うことができます...、改行を含めることができます: n=0; for i in .* *; do ((n++)) ; done ; echo $n(ドロップ*あなたがそれらのものをカウントしたくない場合。)。または:(ls -1d ./.* ./* | grep '^\./' | wc -l ファイル名に「/」を含めることはできません)
オリビエデュラック

3
ls通常、端末への出力にはデフォルトでカラーコードが含まれます。非端末への出力の場合、通常、色はデフォルトで無効になっています。GNUでは、--color={always,auto,never}IIRCです。別の色ではなく色が含まれている場合、出力は画面上で同一に見える場合がありますが、バイトが同じではありません(色コードはlsの出力の一部を形成します)。
CVn

@MichaelKjörlingそれを答えとして書くべきだと思う。
200_success

@MichaelKjörlingそれは私が考慮していない興味深いものです。色や列の出力などの端末オプションを覚えなくても、端末に出力するように常にパイプする一般的な方法はありますか?
ルビスタリオン

@rubystallionそれは良い質問のようですね。
CVn

回答:


26

ls出力が端末に送信されるかどうかをテストします。出力が端末に送られない場合、それ-1がデフォルトです。(これは、のいずれかによって上書きすることができ-C-mまたは-xオプション)。

したがって、lsがパイプラインで使用され、別のオプションで上書きされていない場合、lsを使用します-1この動作はPOSIXで必要とされるため、これに依存できます。

POSIX仕様

POSIXでは-1、出力が端末に送信されない場合は常にデフォルトとして必要です。

POSIX仕様

デフォルトの形式は、標準出力への行ごとに1つのエントリをリストすることです。例外は端末に対するものであるか、-C、-m、または-xオプションのいずれかが指定されている場合です。出力が端末への場合、形式は実装定義です。

デフォルトの単一列形式をオーバーライドするこれらの3つのオプションは次のとおりです。

-C
照合順序に従って、列をソートしたエントリでマルチテキスト列出力を書き込みます。テキスト列の数と列区切り文字は指定されていませんが、出力デバイスの性質に合わせて調整する必要があります。このオプションは、長い形式の出力を無効にします。

-m
ストリーム出力形式。<comma>文字とそれに続く<space>文字で区切られた、ページ全体のパス名をリストします。次のリストエントリの行にスペースがない場合は、リストターミネータとして、およびセパレータシーケンスの後に<newline>文字を使用します。このオプションは、長い形式の出力を無効にします。

-x
-Cと同じです。ただし、複数テキスト列出力は、列ではなく列全体でソートされたエントリで生成されます。このオプションは、長い形式の出力を無効にします。

GNUドキュメント

GNU lsマニュアルから:

'-1'
'--format = single-column'
1行に1つのファイルをリストします。これは、標準出力が端末でない場合のlsのデフォルトです。ファイル名内の改行文字の直接出力を抑制するには、-bおよび-qオプションも参照してください。[エンファシスの追加]

3つのファイルを作成しましょう。

$ touch file{1..3}

出力が端末に送られるとき、GNU lsは複数列形式の使用を選択します。

$ ls
file1  file2  file3

出力がパイプラインに送られる場合、POSIX仕様では、単一列がデフォルトであることが必要です。

$ ls | cat
file1
file2
file3

デフォルトの単一列の動作をオーバーライドする3つの例外は-m、コンマ区切り、-Cソートさ-xれた列、およびソートされた列です。

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3

...しかし、引用は、それが必要であることを示している:「出力が端末になるとPOSIXは、デフォルトとして-1が必要です」-1デフォルトとして除いて出力が端末(または他の条件)になると
muru

@muruそれをキャッチしてくれてありがとう!回答が更新されました。
John1024

まあ、すべての雲には銀の裏地があります。私が投稿される前にあなたの答えが受け入れられたので、ファンキーなピザハットを手に入れました!
G-Manが「Reinstate Monica」と言う

@ G-Manとても良い。そして、ハンサムな帽子です!
John1024

9
  • 標準出力をパイピングすると、動作が変わるのはなぜlsですか?そのように設計されたからです。POSIX仕様は言います:

    デフォルトの形式は、標準出力への行ごとに1つのエントリをリストすることです。例外は端末にあるかのいずれかのとき-C-mまたは-xオプションが指定されています。出力が端末への場合、形式は実装定義です。

    これは、ターミナルへの出力でのデフォルトの動作(-lまたはなどのオプションで指定されていない場合)について実際にはあいまいです。GNUCoreutilsのドキュメントには、-1

    標準出力が端末の場合、出力は列(垂直にソート)にあり、制御文字は疑問符として出力されます。それ以外の場合、出力は1行に1つずつリストされ、制御文字はそのまま出力されます。

    そのため、ファイルへの出力はパイプへの出力と同じように機能することがわかります。つまり、あたかも-1指定されたかのように、1行に1つのエントリがあります。

  • なぜそのように設計されたのですか?確実に知ることは不可能かもしれませんが(誰かがデザインノートを見つけられない限り)、私は推測します:
    • lsターミナルに書き込むときは、人間が出力を見ていることを期待します。人々は必要最小限の行数で情報を取得することを好むので、画面がスクロールすることはありません。
    • lsパイプに書き込むとき、別のプログラムが出力を読み込んでいると想定します。プログラムは、列を解析しようとするよりも、行ごとに1つの値であるデータを読み取る方がはるかに簡単です(ファイル名にスペースを含めることができるため)。
  • ls -1 ファイルまたはパイプに書き込むときに優先する理由はありますか?いや

-4

lsをパイピングするとき、lsはコンソールに実際にある列の数を決定できません(右側のコマンドに依存しません)。したがって、lsは独自の選択でそれを実行します。つまり、この動作は不安定であり、将来のバージョンで変更される可能性があります。

対照的に、ls -1一般的にカウントまたはスクリプト作成を目的として作成されたため、その動作は安定しています。


9
他の回答では、この動作はPOSIXで必要とされているため、不安定と呼ぶのは間違っています。
ヘンリック-モニカの傷を止める
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.