Arquivo para a Tag ‘bash’
Variáveis em subshells
Recentemente enfrentei alguma dificuldade com a contabilização de contadores em shell script durante o processamento de arquivos texto. Para fins didáticos, ilustrarei com um exemplo simples. Imaginem que gostaríamos de saber quantos usuários têm como grupo principal o users. Poderíamos resolver o problema como no exemplo a seguir:
GRUPO=100 # users CONTADOR=0 cat /etc/passwd | while read VALORES do # verifica se grupo do usuario eh o grupo que deve ser contabilizado if [ `echo ${VALORES} | cut -d":" -f4` == ${GRUPO} ] then let CONTADOR++ fi done echo ${CONTADOR}
Sei que existem maneiras mais simples de resolver o problema, mas lembro que é um exemplo didático, com o objetivo de ilustrar a dificuldade que encontrei.
Bom este era o meu raciocínio antes de dar-me conta da questão do subshell criado pelo pipe (|) que adicionei na minha lógica (vejam detalhes sobre o escopo de variáveis em subshells). Quando se faz uso de subshells em progração de shell script, todas as variáveis criadas neste contexto somente são válidas entre o “do” e o “done” (para o caso do exemplo citado).
E qual a solução para o problema então? Bom, como em toda programação, podem existir várias! A primeira tentativa seria contornar o uso de subshells. Para o exemplo citado, seria bastante simples:
GRUPO=100 # users
echo "Número de usuários no grupo ${GRUPO}: `cat /etc/passwd | cut -d":" -f4` | grep ${GRUPO} | wc -l`"
Mas nem sempre a solução pode descartar o uso de subshells. O que fazer então? Uma outra alternativa seria o uso de um arquivo temporário como acumulador:
GRUPO=100 # users TMP="/tmp/contador.tmp" echo 0 > ${TMP} cat /etc/passwd | while read VALORES do # verifica se grupo do usuario eh o grupo que deve ser contabilizado if [ `echo ${VALORES} | cut -d":" -f4` == ${GRUPO} ] then CONTADOR=`cat ${TMP}` let CONTADOR++ echo ${CONTADOR} > ${TMP} fi done echo `cat ${TMP}` rm ${TMP}
Pode não ser uma solução tão elegante, mas é funcional! Se desejarem adicionar mais sugestões, por favor, colaborem.
Deixe um comentário