é canalizado ls o mesmo que ls -1?

18

ls retorna a saída em várias colunas, enquanto ls|cat retorna a mesma saída com ls -1 para os diretórios que tentei. Ainda vejo ls -1 enviado em respostas, como ls -1|wc -l . Existe alguma razão para preferir ls -1 ? Por que ...|cat altera a saída de ls ?

    
por rubystallion 13.12.2017 / 07:43

3 respostas

26

ls testa 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 uma das opções -C , -m ou -x .)

Assim, quando ls é usado em um pipeline e você não o substituiu por outra opção, ls usará -1 . Você pode confiar nisso porque esse comportamento é exigido pelo POSIX

Especificação POSIX

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

A especificação POSIX :

The default format shall be to list one entry per line to standard output; the exceptions are to terminals or when one of the -C, -m, or -x options is specified. If the output is to a terminal, the format is implementation-defined.

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

-C
Write multi-text-column output with entries sorted down the columns, according to the collating sequence. The number of text columns and the column separator characters are unspecified, but should be adapted to the nature of the output device. This option disables long format output.

-m
Stream output format; list pathnames across the page, separated by a <comma> character followed by a <space> character. Use a <newline> character as the list terminator and after the separator sequence when there is not room on a line for the next list entry. This option disables long format output.

-x
The same as -C, except that the multi-text-column output is produced with entries sorted across, rather than down, the columns. This option disables long format output.

Documentação GNU

De manual do GNU ls :

‘-1’
‘--format=single-column’
List one file per line. This is the default for ls when standard output is not a terminal. See also the -b and -q options to suppress direct output of newline characters within a file name. [Emphasis added]

Exemplos

Vamos criar três arquivos:

$ touch file{1..3}

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

$ ls
file1  file2  file3

Quando a saída vai para um pipeline, a especificação POSIX requer 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 -m para separados por vírgula, -C para colunas classificadas como -x para colunas classificadas em:

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3
    
por 13.12.2017 / 07:58
9
  • Por que o piping da saída padrão altera o comportamento de ls ? Porque foi projetado dessa maneira. A especificação POSIX diz:

    The default format shall be to list one entry per line to standard output; the exceptions are to terminals or when one of the -C, -m, or -x options is specified.  If the output is to a terminal, the format is implementation-defined.

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

    If standard output is a terminal, the output is in columns (sorted vertically) and control characters are output as question marks; otherwise, the output is listed one per line and control characters are output as-is.

    Assim, você pode ver que a saída para um arquivo irá agir da mesma forma que a saída para um pipe; ou seja, uma entrada por linha, como se -1 tivesse sido especificado.

  • Por que foi projetado dessa maneira? Pode não ser possível saber com certeza (a menos que alguém possa encontrar algumas notas de projeto), mas eu acho que:
    • Quando ls está gravando em um terminal, espera que um ser humano esteja olhando para a saída. As pessoas preferirão obter informações no mínimo necessário número de linhas, de modo que o material não rola da tela.
    • Quando ls está escrevendo para um pipe, espera que outro programa esteja lendo a saída. É muito mais fácil para um programa ler dados que são um valor por linha do que ter que tentar analisar colunas (já que nomes de arquivos podem conter espaços).
  • Existe alguma razão para preferir ls -1 quando você está escrevendo em um arquivo ou um pipe? Não.
por 13.12.2017 / 08:13
-4

Quando estiver realizando o sls ls, o ls não poderá determinar quantas colunas o console possui (independente do comando do lado direito). Então, eu faço 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 -1 foi criado para fins de contagem ou script em geral, portanto, seu comportamento é estável.

    
por 13.12.2017 / 07:53

Tags