Ao criar um script bash, descobri que este código ls
coloca todos os arquivos em uma linha:
pi@raspberrypi:~/ptlrestinterface$ ls
update.sh web.config MyApp.runtimeconfig.json
ainda ls | head -n1
imprime apenas o primeiro arquivo:
pi@raspberrypi:~/ptlrestinterface$ ls | head -n1
update.sh
Eu esperaria que ele produzisse a linha inteira, não o primeiro arquivo.
Ao canalizar a saída hexdump
, ls
sempre via um 0a
após cada entrada, porém no console ele os coloca um ao lado do outro.
Aparentemente ls
tem algum conhecimento do console (ou do console do ls
). Como isso funciona e onde posso encontrar documentação sobre esse comportamento?
Ele chama a
isatty()
função libc em seustdout
descritor de arquivo para determinar se a saída vai para um terminal ou não.Internamente,
isatty()
tenta usar uma dasioctl()
chamadas específicas para dispositivos tty – provavelmenteioctl(TCGETS)
(que recupera as configurações genéricas de tty que ostty
comando mostra); se tiver sucesso, o arquivo é um dispositivo tty.Isso afeta se ls colocará sua saída em colunas por padrão e se usará cores por padrão, e algumas outras coisas, como se os nomes dos arquivos serão citados.
Se
stdout
for de fato um terminal,ls
use outro específico do ttyioctl(TIOCGWINSZ)
para recuperar suas dimensões (que nos sistemas modernos foram armazenadas lá pelo emulador de terminal) para descobrir quantas colunas ele pode caber. Ostty size
comando também obtém isso; tente executá-lo emstrace
.Os programas de tela cheia reagem adicionalmente ao
SIGWINCH
sinal que o kernel envia toda vez que o emulador de terminal atualiza as dimensões do tty, como uma indicação de que precisam redesenhar tudo no novo tamanho.Para uma explicação menos técnica, observe o que acontece quando você tenta estes dois comandos:
A tubulação
cat
"não faz nada", exceto quels
"avisa" que sua saída está sendo canalizada para algum lugar. Portanto, ele muda seu comportamento de acordo.Depois de entender o que
ls
está sendo gerado, fica claro o que acontece quando ele passahead -n1
.