De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Julio Cezar Neves
Data de Publicação: 18 de julho de 2017
É muito raro vermos um script Shell que trabalhe devidamente com as
opções de stdin, stdout e stderr, ou seja, entrada primária,
saída primária e saída de erros primária. O script a seguir, habilita a
captura dos dados de entrada pelo pipe (|
), por um redirecionamento da
entrada (<
) ou por passagem de parâmetro e manda os erros para a saída
de erros padrão, o que permite redirecionar os erros para onde você desejar,
ou até trancar a saída de erro (2>&-
) para evitar essas mensagens.
$ cat colunador.sh #!/bin/bash # Recebe dados via pipe, arquivo ou passagem de parâmetros e #+ os coloca em coluna numerando-os if [[ -t 0 ]] # Testa se tem dado em stdin then (($# == 0)) || { # Testa se tem parâmetro echo Passe os dados via pipe, arquivo ou passagem de parâmetros >&2 # Redirecionando para stderr exit 1 } Parms="$@" else Parms=$(cat -) # Seta parâmetros com conteúdo de stdin fi set $Parms for ((i=1; i<="$#"; i++)) { Lista=$(for ((i=1; i<="$#"; i++)); { printf "%0${##}i %s\n" $i "${!i}"; }) } echo "$Lista" | column -c $(tput cols) $ echo {A..Z} | colunador.sh 01 A 05 E 09 I 12 L 15 O 18 R 21 U 24 X 02 B 06 F 10 J 13 M 16 P 19 S 22 V 25 Y 03 C 07 G 11 K 14 N 17 Q 20 T 23 W 26 Z 04 D 08 H
Esse script começa testando se o FD 0 (zero), que é o descritor da entrada
primária, está aberto em um terminal e isso ocorrerá se o programa não
estiver recebendo dados por um pipe (|
) ou por um redirecionamento de entrada
(<
). Assim sendo vamos testar se a quantidade de parâmetros passados ($#
)
é zero, ou seja: os dados não vieram por stdin nem por passagem de parâmetros
quando então é indicado um erro, que é desviado para stderr (>&2
).
Bem, agora vamos tratar os dados que recebemos, passando-os para a variável
$Parms
. Caso eles tenham vindo por passagem de parâmetros, aí é simples,
é só atribuir a $Parms
o valor de todos os parâmetros passados ($@
).
Caso os dados tenham vindo de stdin, temos mais 2 macetes:
1. A quase totalidade dos utilitários do Shell, aceitam o hífen como representando os dados recebido de stdin. Veja isso:
$ cat arq Isto é um teste Outra linha de teste $ echo Inserindo uma linha antes de arq | cat - arq Inserindo uma linha antes de arq Isto é um teste Outra linha de teste
Ou seja, o comando primeiramente listou o que recebeu da entrada primária
e em seguida o arquivo arq
.
2. O outro macete é o comando set
. Para entendê-lo vá para o prompt e faça:
$ set a b c
$ echo $1:$2:$3
a:b:c
Conforme você viu, este comando atribuiu os valores passados como os parâmetros posicionais.
Uma vez entendido isso, vimos que os valores recebidos de stdin foram
colocados em $Parms
que por sua vez teve seu conteúdo passado para os
parâmetros posicionais, unificando dessa forma, os dados de qualquer tipo
de entrada recebida.
O for
terminará quando alcançar a quantidade de parâmetros passados ($#
)
e o comando printf
, em seu primeiro parâmetro, (%0${##}d
), diz que a linha
será formatada (%
) com um decimal (d
) com ${##}
algarismos, preenchido com
zeros à esquerda (0).
Veja isso para entender melhor: ${#var}
devolve o tamanho da variável var
e
também sabemos que $#
retorna a quantidade de parâmetros passados. Juntando
os dois, vemos que ${##}
devolve quantos algarismos tem a quantidade de
parâmetros. Faça este teste para você ver:
$ set {a..k} # Passando 11 parâmetros $ echo ${##} algarismos 2 algarismos $ set a b c # Passando 3 parâmetros $ echo ${##} algarismos 1 algarismos
Uma vez montada a lista, é só passá-la para o comando tr
, cuja opção -T
diz que a formatação não é para impressora e o -8
é para dividir a saída
em 8
colunas (trabalhar para que? O Shell já tem comando pronto para tudo!)
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários