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: Júlio Cezar Neves
Data de Publicação: 25 de janeiro de 2018
Um recadinho rápido, a segunda aula do workshop sobre Programação Shell Linux já está no ar. Esta aula chama-se A Programação Shell Linux e tem por objetivo ilustrar os enormes ganhos de produtividade que o conhecimento aprofundado de sistemas GNU/Linux e da programação shell propiciam.
Obviamente o comando if não se enquadra na categoria de "coisas raras de se
ver em Shell" mas é bem diferente do resto, porque aqui o comando if
não testa condição, por incrível que pareça, testa instrução. Experimente
fazer:
VouProcurar=root
if grep -q $VouProcurar /etc/passwd
then
echo $VouProcurar pode se logar
else
echo $VouProcurar não pode se logar
fi
Agora experimente atribuir a VouProcurar um valor que não esteja definido
em /etc/passwd e execute este pedaço de código novamente.
Já que estamos falando em if, você deve estar se pensando: "mas eu sou um
viciado dependente de testar condições. Como fazer isso?"
E eu te garanto: existe um comando chamado test que só testa condições e
para testá-las você usa o if testando o test. Veja:
if ! test -d dir
then
mkdir dir
fi; cd dir
A exclamação nega a pergunta, então eu testo se não existe um diretório (-d)
dir, quando então vou criá-lo. O importante é que ao final dessas linhas
você estará no diretório dir, existisse ele ou não.
Esse negócio de if test ... é muito estranho e por isso o comando test
também pode ser substituido por um ou dois par(es) de colchetes ([...]
ou [[...]]). No mesmo exemplo...
if [ ! -d dir ]
then
mkdir dir
fi; cd dir
Agora vou te contar a mágica: toda instrução manda um código de retorno, que
está na variável $?, e esse código será zero se o comando for bem sucedido,
caso não seja, esse código será diferente de zero e os malucos que fizeram o
interpretador resolveram criar um conector && e outro ||, de tal forma que
se fizermos CMD1 && CMD2, o comando CMD2 só será executado se CMD1 for bem
sucedido, se fosse CMD1 || CMD2, o segundo só será executado caso o primeiro
tenha falhado. Você já deve ter notado que o && equivale ao then e o || ao
else. Então esse test que acabamos de ver, nem precisa do if e pode ficar
de tamanho mínimo se for (bem) escrito assim:
[ -d dir ] || mkdir dir; cd dir
Ou:
[[ -d dir ]] || mkdir dir; cd dir
Você sabe pegar um dado vindo pelo pipe ou redirecionado para seu
script? Não? Isso é porque você não conhece bem o comando test. Com a opção
-t FD ele testa se o descritor FD está aberto no seu terminal. Ora,
como sabemos que a entrada primária tem o descritor zero, podemos fazer:
[[ -t 0 ]] || echo Tem entrada primária
Mas isso não vai te resolver, você precisa saber quais são os parâmetros passados, então faça:
[[ -t 0 ]] || echo Recebi $(cat -)
Vamos aproveitar essa linha: crie um arquivo chamado vemdopipe.sh com os
seguintes dados:
$ cat vemdopipe.sh
[[ -t 0 ]] || echo "Recebi pela entrada primária (pipe ou redirecionamento) $(cat -)"
[[ -n "$@" ]] && echo Recebi os seguintes parâmetros: $@
em seguida vamos torná-lo executável, faça:
$ chmod +x vemdopipe.sh # Ou chmod 755 vemdopipe.sh
E para testá-lo faça:
$ echo F{a,o,in,us}ca | vemdopipe.sh
$ vemdopipe.sh F{a,o,in,us}ca
$ vemdopipe.sh < /etc/passwd
Viu!? O bacalho agora está apto a receber o dado venha lá de onde ele vier!