web-dev-qa-db-ja.com

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

lsはいくつかの列で出力を返しますが、ls|catは、私が試したディレクトリに対してls -1でバイト単位の出力を返します。それでも、ls -1のように、ls -1|wc -lがパイプで返されます。 ls -1を選ぶ理由はありますか? ...|catlsの出力を変更するのはなぜですか?

19
rubystallion

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

したがって、lsがパイプラインで使用されていて、それを別のオプションでオーバーライドしていない場合、ls-1を使用します。 この動作はPOSIXで必要とされるため、これを信頼できます。

POSIX仕様

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

POSIX仕様

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

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

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

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

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

GNUドキュメント

から GNU ls manual

‘-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
26
John1024
  • 標準出力をパイプするとlsの動作が変わるのはなぜですか?それがそのように設計されたからです。 POSIX仕様 は次のように述べています。

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

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

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

    したがって、ファイルへの出力がパイプへの出力と同じように機能することがわかります。つまり、-1が指定されている場合と同様に、1行に1つのエントリがあります。

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