il piping è uguale a ls -1?


19

lsrestituisce output in più colonne, mentre ls|catrestituisce output identico a byte con ls -1per le directory che ho provato. Ancora vedo ls -1convogliato nelle risposte, come ls -1|wc -l. C'è mai un motivo per preferire ls -1? Perché ...|catcambia l'output di ls?


1
i nomi dei file potrebbero contenere newline, quindi potresti contarli più volte ... Puoi invece fare posix: n=0; for i in .* *; do ((n++)) ; done ; echo $n(rilascia il. * se non vuoi contarli). oppure: ls -1d ./.* ./* | grep '^\./' | wc -l (poiché i nomi dei file non possono contenere '/')
Olivier Dulac il

3
lsl'output su un terminale generalmente include codici colore per impostazione predefinita. Per l'output su un non terminale, il colore è in genere disabilitato per impostazione predefinita. In GNU, questo è --color={always,auto,never}IIRC. Se il colore è incluso in uno ma non nell'altro, le uscite possono apparire identiche sullo schermo, ma non sono identiche ai byte (i codici colore fanno parte dell'output di ls).
un CVn il

@ MichaelKjörling Penso che dovresti scriverlo come risposta.
200_successo

@ MichaelKjörling È qualcosa di interessante che non ho considerato. Esiste un modo generale per reindirizzare sempre come se si stesse inviando al terminale senza dover ricordare le opzioni del terminale per l'output di colore e colonna, ecc.?
Rubystallion,

@rubystallion Sembra una buona domanda separata.
un CVn il

Risposte:


26

lsverifica se l'output sta andando a un terminale. Se l'output non sta andando a un terminale, allora -1è l'impostazione predefinita. (Questo può essere sovrascritto da uno dei -C, -mo -xopzioni.)

Pertanto, quando lsviene utilizzato in una pipeline e non è stato ignorato con un'altra opzione, lsverrà utilizzato -1. Puoi fare affidamento su questo perché questo comportamento è richiesto da POSIX

Specifica POSIX

POSIX richiede -1come predefinito ogni volta che l'output non sta andando su un terminale:

Le specifiche POSIX :

Il formato predefinito è quello di elencare una voce per riga nell'output standard; le eccezioni sono ai terminali o quando viene specificata una delle opzioni -C, -m o -x. Se l'output è su un terminale, il formato è definito dall'implementazione.

Queste tre opzioni che sovrascrivono il formato predefinito a colonna singola sono:

-C
Scrive l'output di più colonne di testo con le voci ordinate in basso nelle colonne, secondo la sequenza di confronto. Il numero di colonne di testo e i caratteri di separazione delle colonne non sono specificati, ma devono essere adattati alla natura del dispositivo di output. Questa opzione disabilita l'output di formato lungo.

-m
Formato di output dello stream; elenca i percorsi nella pagina, separati da un carattere <comma> seguito da un carattere <spazio>. Utilizzare un carattere <newline> come terminatore di elenco e dopo la sequenza di separazione quando non vi è spazio su una riga per la voce di elenco successiva. Questa opzione disabilita l'output di formato lungo.

-x
Lo stesso di -C, tranne per il fatto che l'output di più colonne di testo viene prodotto con voci ordinate attraverso, anziché verso il basso, le colonne. Questa opzione disabilita l'output di formato lungo.

Documentazione GNU

Dal manuale di GNU :

'-1'
'--format = single-column'
Elenca un file per riga. Questo è il valore predefinito per ls quando l'output standard non è un terminale . Vedi anche le opzioni -b e -q per sopprimere l'output diretto di caratteri di nuova riga all'interno di un nome file. [Enfasi aggiunta]

Esempi

Creiamo tre file:

$ touch file{1..3}

Quando l'output arriva a un terminale, GNU lssceglie di usare un formato multi-colonna:

$ ls
file1  file2  file3

Quando l'output arriva a una pipeline, le specifiche POSIX richiedono che la colonna singola sia l'impostazione predefinita:

$ ls | cat
file1
file2
file3

Le tre eccezioni che sovrascrivono il comportamento predefinito a colonna singola sono -mper la virgola separata, -Cper le colonne ordinate in basso e -xper le colonne ordinate in:

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

"POSIX richiede -1 come impostazione predefinita quando l'output viene indirizzato a un terminale:" ... ma la virgoletta indica che richiede -1come impostazione predefinita tranne quando l'output arriva al terminale (o altre condizioni)
muru

@muru Grazie per averlo catturato! Risposta aggiornata
Giovanni 1024

Bene, ogni nuvola ha un rivestimento d'argento. Perché la tua risposta è stata accettata prima che la mia fosse pubblicata, ho ottenuto un cappello da pizza funky!
G-Man dice 'Reinstate Monica' il

@ G-Man Molto bene. E, è un bel cappello!
Giovanni 1024,

9
  • Perché il piping dell'output standard cambia il comportamento di ls? Perché è stato progettato in questo modo. Le specifiche POSIX indicano :

    Il formato predefinito è quello di elencare una voce per riga nell'output standard; le eccezioni devono terminali o quando uno dei -C, -mo -xè specificato opzioni. Se l'output è su un terminale, il formato è definito dall'implementazione.

    che è in realtà ambiguo riguardo al comportamento predefinito (quando non specificato da un'opzione come -lo -1) con output su un terminale, e la documentazione di GNU Coreutils dice

    Se l'output standard è un terminale, l'output è in colonne (ordinate verticalmente) e i caratteri di controllo vengono emessi come punti interrogativi; in caso contrario, l'output viene elencato uno per riga e i caratteri di controllo vengono emessi così come sono.

    Quindi puoi vedere che l'output su un file agirà come l'output su una pipe; vale a dire una voce per riga, come se -1fosse stata specificata.

  • Perché è stato progettato in questo modo? Potrebbe non essere possibile saperlo con certezza (a meno che qualcuno non riesca a trovare alcune note di progettazione), ma credo:
    • Quando lssta scrivendo su un terminale, si aspetta che un essere umano stia guardando l'output. Le persone preferiranno ottenere informazioni nel numero minimo necessario di righe, quindi le cose non scorreranno sullo schermo.
    • Quando lssta scrivendo su una pipe, si aspetta che un altro programma stia leggendo l'output. È molto più facile per un programma leggere dati con un valore per riga piuttosto che dover analizzare le colonne (poiché i nomi dei file possono contenere spazi).
  • C'è mai un motivo per preferire ls -1 quando scrivi su un file o una pipe? No.

-4

Quando si effettua il piping ls, ls non può determinare quante colonne ha effettivamente la console (indipendentemente dal comando sul lato destro). Quindi lo fa solo per sua scelta o, in altre parole, questo comportamento è instabile e potrebbe cambiare nelle versioni future.

Al contrario, è ls -1stato creato allo scopo di contare o scrivere script in generale, quindi il suo comportamento è stabile.


9
Come dicono le altre risposte questo comportamento è richiesto da POSIX, quindi chiamarlo instabile è sbagliato.
Henrik - smetti di ferire Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.