Shell scripts - Bash O conteú desse cumento é de autoria Prof. Dr. Carlos Maziero Conteú Obti em: http://www.ppgia.pucpr.br/~maziero/ku.php/unix:shell_scripts Estrutura geral de um script Shell Os arquivos de script permitem construir esquemas de execução complexos a partir s comans básicos shell. A forma mais elementar de arquivo de script é apenas um conjunto de comans em um arquivo texto, com permissões de execução habilitadas. O arquivo backup, cujo conteú é mostra a seguir, é um exemplo de script: echo "Inician backup" # montar o diretório servir de backup mount backserver.ppgia.pucpr.br:/backup /backup # efetuar o backup em um arquivo tar compacta tar czf /backup/home.tar.gz /home # desmontar o diretório servir de backup umount /backup echo "Backup conclui!" Quan o script backup for executa, os comans arquivo serão executas em seqüência pelo shell corrente (de onde ele foi lança). Assim, se o usuário estiver usan o shell bash, os comans script serão executas por esse shell. Como isso poderia gerar problemas em scripts usas por vários usuários, é possível forçar a execução script com um shell especíco (ou outro programa que interprete os comans arquivo). Para isso é necessário informar ao sistema operacional o programa a ser usa, na primeira linha arquivo script: #!/bin/bash --noprole # A opção --noprole inibe a leitura s arquivos de inicialização # shell, tornan o lançamento script muito mais rápi. # comans de um script em Bash-Shell server=backserver.ppgia.pucpr.br backdir=/backup exit 0 Com isso, será lança um shell Bash separa (um novo processo), somente para interpretar as instruções script. O novo processo será termina pelo coman exit, cujo parâmetro é devolvi ao shell anterior através da variável $?. Esse procedimento pode ser usa para lançar scripts para outros shells, ou mesmo outras linguagens interpretadas, como Perl, Awk, Sed, Php, Python, etc. Parâmetros de entrada Os argumentos da linha de coman são passas para o shell através da variável local $argv. Os campos individuais dessa variável podem ser acessas como em uma variável local
qualquer. Além disso, uma série de atalhos é denida para facilitar o acesso a esses parâmetros: $0 : o nome script $n : o n-ésimo argumento da linha de coman $* : tos os argumentos da linha de coman $# : número de argumentos $? : status último coman executa (status <> 0 indica erro) $$ : número de processo (PID) shell que executa o script Eis um exemplo através script listaparams: #!/bin/bash # exemplo de uso s parâmetros de entrada echo "Nome script : $0" echo "Primeiro parâmetro : $1" echo "Tos os parâmetros : $*" echo "Numero de parametros : $#" echo "Numero deste processo : $$" exit 0 Chaman o script acima com alguns parâmetros se obtém a seguinte resposta: ~> listaparams banana tomate pessego melao pera uva Nome script : listaparams Primeiro parâmetro : banana Tos os parâmetros : banana tomate pessego melao pera uva Numero de parametros : 6 Numero deste processo : 2215 ~> Controle de fluxo Existem diversos construtores de controle de fluxo que podem ser usas em scripts BASH-Shell. Os principais são descritos a seguir. Condições Como na maioria das linguagens, no shell Bash, testes de condições são realizas por estruturas tipo if--. As condições testadas são os status de saída da execução de comans (o valor inteiro retorna pela chamada de sistema exit() coman). Caso o status seja zero (0), a condição é considerada verdadeira: if cmp $le1 $le2 >/dev/null # testa o status coman cmp echo "os arquivos são iguais" echo "os arquivos são distintos" Essa lógica ao contrário pode causar uma certa confusão aos iniciantes. Assim, para simplicar a programação de scripts, é deni um operar test condition, que também pode ser representa por [ condition ] e retorna zero (0) se a condição testada for verdadeira: if [ $n1 -lt $n2 ] # $n1 é menor que $n2?
echo "$n1 é menor que $n2" if test $n1 -lt $n2 # $n1 é menor que $n2? echo "$n1 é menor que $n2" Os principais operares de teste disponíveis são: Operar if- if coman # testa o status coman cmp if cmp le1 le2 >/dev/null echo "Os arquivos são iguais" Operar if-- if coman # testa a existência de $le1 if [ -e "$le1" ] echo "$le1 existe" echo "$le1 não existe" Operar if--elif- if coman 1 elif coman 2
# compara as variáveis $n1 e $n2 if [ $n1 -lt $n2 ] echo "$n1 < $n2" elif [ $n1 -gt $n2 ] echo "$n1 > $n2" echo "$n1 = $n2" Operar case case variável in "string1") break;; "string2") break;; *): break;; esac case $opt in "-c") complete=1 ;; "-s") short=1 ; name="" ;; *) echo "opção $opt desconhecida" ; exit 1 ;; esac Os principais tipos de teste disponíveis são: Comparações entre números -eq : igual a -ne : diferente de -gt : maior que -ge : maior ou igual a -lt : menor que -le : menor ou igual a -a : AND binário (bit a bit) -o : OR binário (bit a bit) Comparações entre strings usan [] = : igual a!= : diferente de -z : string de tamanho zero
Comparações entre strings usan [[]] <= : menor ou igual a (lexicográco) >= : maior ou igual a (lexicográco) Associações entre condições && : AND lógico : OR lógico Os operares de teste em arquivos permitem vericar propriedades de entradas no sistema de arquivos. Eles são usas na forma -op, onde op corresponde ao teste deseja. Os principais testes são: e : a entrada existe r : a entrada pode ser lida w : a entrada pode ser escrita O : o usuário é o proprietário da entrada s : tem tamanho maior que zero f : é um arquivo normal d : é um diretório L : é um link simbólico b : é um dispositivo orienta a bloco c : é um dispositivo orienta a caracatere p : é um named pipe (fo) S : é um socket special le u : tem o bit SUID habilita g : tem o bit SGID habilita G : grupo da entrada é o mesmo proprietário k : o stick bit está habilita x : a entrada pode ser executada nt : Verica se um arquivo é mais novo que outro ot : Verica se um arquivo é mais velho que outro ef : Verica se é o mesmo arquivo (link) Eis um exemplo de uso de testes em arquivos: arquivo='/etc/passwd' if [ -e $arquivo ] if [ -f $arquivo ] if [ -r $arquivo ] source $arquivo echo "Nao posso ler o arquivo $arquivo" echo "$arquivo não é um arquivo normal"
echo "$arquivo não existe" Laços Laço for for variável in lista de valores ne for i in *.c echo "compilan $i" cc -c $i ne Laço while while condição ne i=0 while [ $i -lt 10 ] echo $i let i++ ne Operar select select variável in lista de valores ne select f in "abacate" "pera" "uva" "banana" "morango" echo "Escolheu $f" ne Além das estruturas acima, algumas outras podem ser usadas para executar comans em situações especícas: `coman` : substitui a expressão entre crases pelo resulta (stut) da execução coman. Por exemplo, a linha de coman abaixo coloca na variável arqs os nomes de arquivos retornas pelo coman nd: arqs=`nd /etc -type f -iname '???'`
coman1; coman2; coman3 : executa seqüencialmente os comans indicas Operares aritméticos Variáveis conten números inteiros podem ser usadas em expressões aritméticas e lógicas. A atribuição resulta de uma expressão aritmética a uma variável pode ser feita de diversas formas. Por exemplo, as três expressões a seguir têm o mesmo efeito: i=$((j + k)) let i=j+k i=`expr $j + $k` Os principais operares aritméticos disponíveis são: + - * / : aritmética básica ** : potenciação % : módulo (resto) += -= *= /= %= : aritmética e atribuição (como em C) << >> : deslocamento de bits <<= >>= : deslocamento e atribuição & : AND e OR binários &= = : AND e OR binários com atribuição! : NOT binário ^ : XOR binário && : AND e OR lógicos