
Ao tentar decifrar alguns scripts escritos por ex-funcionários da minha empresa atual, em muitos dos scripts, me deparei com as seguintes instruções que atribuem variáveis a alguns comandos conforme mostrado abaixo:
CAT=cat
GREP=grep
SED=sed
Posteriormente no script, vejo que eles usaram essas variáveis em vez dos comandos regulares:
$GREP -v "^#" `dirname $0`/abcdfilename | while read line
do
<some loop operations>
done
Não vejo sentido em usar essa variável em vez de usar grep
diretamente. Minhas perguntas são:
- Faz sentido fazer o grep ou sed (no nosso caso) dessa maneira?
- Isso é resultado de alguém tentando escrever um roteiro com a intenção de dificultar a compreensão de outra pessoa?
- Ou isso é simplesmente um exemplo de script incorreto?
Responder1
Existem diferentes implementações para um comando padrão em um sistema. Como no Solaris 10 e versões anteriores, você tem /bin/sh
o antigo shell Bourne e /usr/xpg4/bin/sh
é compatível com POSIX. Ou no OSX, você tem BSD sed ao ligar sed
e GNU sed ao chamar gsed
. Você pode escolher qual implementação deseja usar em seu script.
Portanto, é mais fácil alterar a implementação do seu script quando você usa variável. Quando você quiser o GNU sed:
SED=gsed
Se você não usar variável, deverá substituir todas as ocorrências de sed
em seu script. Embora você possa fazer isso facilmente, é considerada uma má prática de programação.
Responder2
Há um argumento para transformar quase tudo que você usa repetidamente em um script em uma variável, porque então você pode redefini-lo uma vez e fazer com que ele se espalhe pelo resto do script.
Você pode argumentar que basicamente a mesma coisa poderia ser feita com uma simples pesquisa/substituição sed, mas muitos usuários são cautelosos com a pesquisa/substituição, já que não é tão difícil substituir acidentalmente algo que você não pretendia substituir.
Na verdade, eu sugeriria esta melhoria em relação à versão existente:
GREP=${GREP:-/bin/grep}
o que significa que GREP será definido como o que o usuário definir no shell ou, se NÃO estiver definido, então como /bin/grep
Dessa forma, um usuário pode substituir o 'grep' imediatamente.
$ export GREP=/bin/fgrep
$ ./path/to/script.sh
Responder3
Provavelmente é um exemplo de otimização prematura.
Quantas alternativas essa máquina, ouqualquermáquina tem parased,grep, eestranho? Aposto que a média universal está próxima de 1,0. Dadas duas opções em uma máquina específica, quais são as chances de as implementações diferirem de tal forma que o script falhe com a versão encontrada no PATH e funcione com a outra? Se isso acontecer, é mais provável que a solução altere o script ou o PATH? Se mudar o script for a resposta, quais são as chances de encontrar pelo menos uma invocação degrepem vez de$GREP? O baralho está contra a necessidade de qualquer indireção e contra o funcionamento pretendido, se for necessário.
Eu não lutaria contra a cultura. Se houver alguma preferência em sua loja por$GREPou/usr/bin/grepou apenasgrep, eu provavelmente iria junto para me dar bem. Caso contrário, KISS: evite indireções até que surja a necessidade.