é canalizado o mesmo que ls -1?

19

lsretorna a saída em várias colunas, enquanto ls|catretorna saída idêntica a byte ls -1para os diretórios que tentei. Ainda vejo ls -1respostas encanadas, como ls -1|wc -l. Existe alguma razão para preferir ls -1? Por que ...|catalterar a saída de ls?

rubystallion
fonte
1
os nomes de arquivos podem conter novas linhas, portanto, você deve contá-las várias vezes ... em vez disso, pode: n=0; for i in .* *; do ((n++)) ; done ; echo $n(largar o. * se não quiser contar essas). ou: ls -1d ./.* ./* | grep '^\./' | wc -l (como os nomes dos arquivos não podem conter '/')
Olivier Dulac
3
lsa saída para um terminal geralmente inclui códigos de cores por padrão. Para saída para um não terminal, a cor geralmente é desativada por padrão. No GNU, isso é --color={always,auto,never}IIRC. Se a cor estiver incluída em uma, mas não na outra, as saídas poderão parecer idênticas na tela, mas não serão byte idênticas (os códigos de cores fazem parte da saída de ls).
um CVn
@ MichaelKjörling Acho que você deveria escrever isso como resposta.
200_success
@ MichaelKjörling Isso é algo interessante que eu não considerei. Existe uma maneira geral de sempre canalizar como se estivesse saindo para o terminal sem precisar se lembrar das opções do terminal para saída de cores e colunas, etc.?
rubystallion
@ Rubystallion Isso soa como uma boa pergunta separada.
um CVn

Respostas:

26

lstesta se a saída está indo para um terminal. Se a saída não estiver indo para um terminal, então -1é o padrão. (Isso pode ser substituído por um dos -C, -mou -xopções.)

Portanto, quando lsfor usado em um pipeline e você não o tiver substituído por outra opção, lsserá usado -1. Você pode confiar nisso porque esse comportamento é exigido pelo POSIX

Especificação POSIX

O POSIX requer -1como padrão sempre que a saída não for para um terminal:

A especificação POSIX :

O formato padrão será listar uma entrada por linha na saída padrão; as exceções são para terminais ou quando uma das opções -C, -m ou -x é especificada. Se a saída for para um terminal, o formato é definido pela implementação.

Essas três opções que substituem o formato padrão de coluna única são:

-C
Grava a saída da coluna de texto múltiplo com entradas classificadas nas colunas, de acordo com a sequência de intercalação. O número de colunas de texto e os caracteres separadores de coluna não são especificados, mas devem ser adaptados à natureza do dispositivo de saída. Esta opção desativa a saída de formato longo.

-m
formato de saída Stream; listar nomes de caminho na página, separados por um caractere <comma> seguido por um caractere <space>. Use um caractere <newline> como terminador da lista e após a sequência separadora quando não houver espaço em uma linha para a próxima entrada da lista. Esta opção desativa a saída de formato longo.

-x
O mesmo que -C, exceto que a saída da coluna de texto múltiplo é produzida com entradas classificadas nas colunas, em vez de para baixo. Esta opção desativa a saída de formato longo.

Documentação GNU

No manual GNU ls :

'-1'
'--format = coluna única'
Liste um arquivo por linha. Esse é o padrão para ls quando a saída padrão não é um terminal . Consulte também as opções -b e -q para suprimir a saída direta de caracteres de nova linha em um nome de arquivo. [Enfase adicionada]

Exemplos

Vamos criar três arquivos:

$ touch file{1..3}

Quando a saída vai para um terminal, o GNU lsescolhe usar um formato de várias colunas:

$ ls
file1  file2  file3

Quando a saída vai para um pipeline, a especificação POSIX exige que a coluna única seja o padrão:

$ ls | cat
file1
file2
file3

As três exceções que substituem o comportamento padrão de coluna única são -mseparadas por vírgula, -Cordenadas -xpor colunas e ordenadas por:

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3
John1024
fonte
"POSIX requer -1 como padrão quando a saída vai para um terminal:" ... mas a cotação indica que exige -1como padrão, exceto quando a saída vai para o terminal (ou outras condições)
muru
Obrigado por capturar isso! Resposta atualizada.
John1024
Bem, toda nuvem tem um forro de prata. Como sua resposta foi aceita antes que a minha fosse publicada, recebi um chapéu de pizza descolado!
G-Man diz 'Reinstate Monica'
@ G-Man Muito bom. E, é um lindo chapéu!
John1024
9
  • Por que canalizar a saída padrão altera o comportamento de ls? Porque foi projetado dessa maneira. A especificação POSIX diz:

    O formato padrão será listar uma entrada por linha na saída padrão; as exceções são para os terminais, ou quando um dos -C, -mou -xopções é especificado. Se a saída for para um terminal, o formato é definido pela implementação.

    que é realmente ambíguo sobre o comportamento padrão (quando não especificado por uma opção como -lou -1) com saída para um terminal, e a documentação do GNU Coreutils diz

    Se a saída padrão for um terminal, a saída será em colunas (classificadas verticalmente) e os caracteres de controle serão exibidos como pontos de interrogação; caso contrário, a saída será listada uma por linha e os caracteres de controle serão exibidos como estão.

    Então você pode ver que a saída para um arquivo funcionará da mesma forma que a saída para um pipe; isto é, uma entrada por linha, como se -1tivesse sido especificada.

  • Por que foi projetado dessa maneira? Pode não ser possível ter certeza (a menos que alguém possa encontrar algumas notas de design), mas acho que:
    • Quando lsestá gravando em um terminal, espera que um ser humano esteja observando a saída. As pessoas preferem obter informações no número mínimo necessário de linhas, para que as coisas não rolem na tela.
    • Quando lsestá gravando em um canal, espera que outro programa esteja lendo a saída. É muito mais fácil para um programa ler dados com um valor por linha do que precisar analisar colunas (já que os nomes de arquivos podem conter espaços).
  • Existe alguma razão para preferir ls -1 quando você está gravando em um arquivo ou canal? Não.
G-Man Diz 'Reinstate Monica'
fonte
-4

Ao canalizar ls, ls não pode determinar quantas colunas o console realmente possui (independente do comando do lado direito). Então, basta fazer isso por sua própria escolha ou, em outras palavras, esse comportamento é instável e pode mudar em versões futuras.

Por outro lado, ls -1foi criado com a finalidade de contar ou criar scripts em geral, portanto, seu comportamento é estável.

xanoetux
fonte
9
Como as outras respostas dizem que esse comportamento é exigido pelo POSIX, chamar isso de instável está errado.
Henrik - pare de machucar Monica