ist die Leitung gleich der Leitung -1?

19

lsGibt die Ausgabe in mehreren Spalten zurück, während die ls|catAusgabe ls -1für Verzeichnisse, die ich ausprobiert habe, Byte-identisch ist . Trotzdem sehe ich ls -1in Antworten wie gepiped ls -1|wc -l. Gibt es jemals einen Grund, es vorzuziehen ls -1? Warum ändert ...|catsich die Ausgabe von ls?

Rubystallion
quelle
1
Dateinamen könnten Zeilenumbrüche enthalten, also würden Sie diese mehrmals zählen ... Sie könnten stattdessen posixly tun: n=0; for i in .* *; do ((n++)) ; done ; echo $n(lassen Sie das. * fallen, wenn Sie diese nicht zählen möchten). oder: ls -1d ./.* ./* | grep '^\./' | wc -l (da Dateinamen nicht '/' enthalten dürfen)
Olivier Dulac
3
lsDie Ausgabe an ein Terminal enthält standardmäßig Farbcodes. Für die Ausgabe auf einem Nicht-Terminal ist die Farbe normalerweise standardmäßig deaktiviert. In GNU ist das --color={always,auto,never}IIRC. Wenn Farbe in einer, aber nicht in einer anderen enthalten ist, erscheinen die Ausgaben auf dem Bildschirm möglicherweise identisch, sind jedoch nicht byteidentisch (Farbcodes sind Teil der Ausgabe von ls).
ein Lebenslauf vom
@ MichaelKjörling Ich finde du solltest das als Antwort schreiben.
200_success
@ MichaelKjörling Das ist etwas Interessantes, das ich nicht bedacht habe. Gibt es eine allgemeine Möglichkeit, die Pipe immer so auszuführen, als ob die Ausgabe an ein Terminal erfolgt, ohne dass die Terminaloptionen für die Farb- und Spaltenausgabe usw. berücksichtigt werden müssen?
Rubystallion
@rubystallion Das klingt nach einer guten separaten Frage.
ein Lebenslauf

Antworten:

26

lsTestet, ob die Ausgabe an ein Terminal gesendet wird. Wenn die Ausgabe nicht an ein Terminal gesendet wird, -1ist dies die Standardeinstellung. (Dies kann durch eine der außer Kraft gesetzt werden -C, -moder -xOptionen.)

Wenn lsalso in einer Pipeline verwendet wird und Sie sie nicht mit einer anderen Option überschrieben haben, lswird verwendet -1. Darauf können Sie sich verlassen, da dieses Verhalten von POSIX gefordert wird

POSIX-Spezifikation

POSIX erfordert -1als Standard, wann immer die Ausgabe nicht an ein Terminal geht:

Die POSIX-Spezifikation :

Das Standardformat besteht darin, einen Eintrag pro Zeile für die Standardausgabe aufzulisten. Ausnahmen sind Terminals oder die Angabe einer der Optionen -C, -m oder -x. Wenn die Ausgabe an ein Terminal erfolgt, ist das Format implementierungsdefiniert.

Diese drei Optionen, die das standardmäßige einspaltige Format überschreiben, sind:

-C
Schreiben Sie eine Ausgabe in mehreren Textspalten mit Einträgen, die nach der Sortierfolge in den Spalten sortiert sind. Die Anzahl der Textspalten und die Spaltentrennzeichen sind nicht angegeben, sollten jedoch an die Art des Ausgabegeräts angepasst werden. Diese Option deaktiviert die Ausgabe im Langformat.

-m
Stream Ausgabeformat; Listen Sie die Pfadnamen auf der Seite auf, getrennt durch ein <Komma>, gefolgt von einem <Leerzeichen>. Verwenden Sie ein <newline> -Zeichen als Listenabschlusszeichen und nach der Trennzeichenfolge, wenn in einer Zeile kein Platz für den nächsten Listeneintrag vorhanden ist. Diese Option deaktiviert die Ausgabe im Langformat.

-x Entspricht
-C, mit der Ausnahme, dass die Ausgabe in mehreren Textspalten mit Einträgen erstellt wird, die über die Spalten hinweg und nicht nach unten sortiert sind. Diese Option deaktiviert die Ausgabe im Langformat.

GNU-Dokumentation

Aus dem GNU-Handbuch :

'-1'
'--format = einspaltig' Listet
eine Datei pro Zeile auf. Dies ist die Standardeinstellung für ls, wenn die Standardausgabe kein Terminal ist . Siehe auch die Optionen -b und -q, um die direkte Ausgabe von Zeilenumbrüchen innerhalb eines Dateinamens zu unterdrücken. [Betonung hinzugefügt]

Beispiele

Lassen Sie uns drei Dateien erstellen:

$ touch file{1..3}

Wenn die Ausgabe an ein Terminal geht, lswählt GNU die Verwendung eines mehrspaltigen Formats:

$ ls
file1  file2  file3

Wenn die Ausgabe an eine Pipeline gesendet wird, erfordert die POSIX-Spezifikation, dass die Standardeinstellung einspaltig ist:

$ ls | cat
file1
file2
file3

Die drei Ausnahmen, die das Standardverhalten für einzelne Spalten außer Kraft setzen, gelten -mfür kommagetrennte, -Cnach unten sortierte und -xnach oben sortierte Spalten:

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3
John1024
quelle
"POSIX erfordert standardmäßig -1, wenn die Ausgabe an ein Terminal -1
gesendet wird
@muru Danke, dass du das erwischt hast! Antwort aktualisiert.
John1024
Nun, jede Wolke hat einen Silberstreifen. Weil deine Antwort akzeptiert wurde, bevor meine veröffentlicht wurde, habe ich einen funky Pizzahut bekommen!
G-Man sagt, dass Monica
@ G-Man Sehr gut. Und ein hübscher Hut ist es!
John1024
9
  • Warum ändert das Leiten der Standardausgabe das Verhalten von ls? Weil es so konzipiert wurde. Die POSIX-Spezifikation besagt:

    Das Standardformat besteht darin, einen Eintrag pro Zeile für die Standardausgabe aufzulisten. Ausnahmen sind an den Klemmen oder wenn einer der -C, -moder -xist Optionen angegeben. Wenn die Ausgabe an ein Terminal erfolgt, ist das Format implementierungsdefiniert.

    Das ist eigentlich mehrdeutig über das Standardverhalten (wenn nicht durch eine Option wie -loder angegeben -1) bei der Ausgabe auf ein Terminal, und die GNU Coreutils-Dokumentation sagt

    Wenn die Standardausgabe ein Terminal ist, erfolgt die Ausgabe in Spalten (vertikal sortiert) und Steuerzeichen werden als Fragezeichen ausgegeben. Andernfalls wird die Ausgabe zeilenweise aufgelistet und die Steuerzeichen werden unverändert ausgegeben.

    Sie können also sehen, dass die Ausgabe in eine Datei genauso funktioniert wie die Ausgabe in eine Pipe. das heißt, ein Eintrag pro Zeile, als ob -1angegeben worden wäre.

  • Warum wurde es so entworfen? Es ist möglicherweise nicht möglich, es genau zu wissen (es sei denn, jemand findet einige Konstruktionsnotizen), aber ich schätze:
    • Wenn lsin ein Terminal geschrieben wird, wird erwartet, dass ein Mensch auf die Ausgabe schaut. Die Leute werden es vorziehen, Informationen in der minimal erforderlichen Anzahl von Zeilen zu erhalten, damit nichts über den Bildschirm rollt.
    • Beim lsSchreiben in eine Pipe wird erwartet, dass ein anderes Programm die Ausgabe liest. Es ist für ein Programm viel einfacher, Daten zu lesen, bei denen es sich um einen Wert pro Zeile handelt, als zu versuchen, Spalten zu analysieren (da Dateinamen Leerzeichen enthalten können).
  • Gibt es jemals einen Grund, es vorzuziehen, ls -1 wenn Sie in eine Datei oder eine Pipe schreiben? Nein.
G-Man sagt, "Monica wiedereinsetzen"
quelle
-4

Wenn ls weitergeleitet wird, kann ls nicht bestimmen, wie viele Spalten die Konsole tatsächlich enthält (unabhängig vom Befehl auf der rechten Seite). Dies geschieht also nach eigener Wahl, oder mit anderen Worten, dieses Verhalten ist instabil und kann sich in zukünftigen Versionen ändern.

Wurde im Gegensatz ls -1dazu zum Zählen oder Erstellen von Skripten im Allgemeinen erstellt, sodass das Verhalten stabil ist.

xanoetux
quelle
9
Wie die anderen Antworten besagen, ist dieses Verhalten für POSIX erforderlich, so dass es falsch ist, es instabil zu nennen.
Henrik - hör auf, Monica