Introdução
Esta página contém uma série de scrips shell para usos diversos. Cadastre-se também na lista de shell script do yahoo http://br.dir.groups.yahoo.com/group/shell-script/ e descubra tudo que pode fazer com shell script
Listas e dicas
Scripts
Manual shell script
Essa apostila está em formato *.ps no kurumin linux use o comando ps2pdf para gerar um pdf.
Atalhos do konsole
^ ---> leia Control
^L ........... limpar a tela
^w ........... apagar palavra anterior
^e ........... vai para o final da linha
^a ........... vai para o começo da linha
^f ........... avança um caractere
^b ........... recua um caractere
Mf ........... avança uma palavra
Mb ........... recua uma palavra
^u ........... recorta do ponto atual até o começo da linha
^y ........... cola o que foi recortado
^d ........... faz logof
^k ........... recorta até o final da linha
^r ........... abre o histórico no modo de procura inversa
M. .......... recupera o último parâmetro do último comando
modificando a variável $PS1
$PS1 é o prompt, veja um exemplo de configuração desta variável com cores
export PS1='[�33[01;33m]t [�33[01;32m]u@h �33[01;34m]w $ [�33[00m]'/*{{{*//*}}}*/
Testando variáveis
#!/bin/ksh
# twofiles script handles two files named on the command line
# a usage function to display help for the hapless user
# plus an additional error message if it has been filled in
usage ()
{
echo "twofiles"
echo "usage: twofiles file1 file2"
echo "Processes two files"
echo " "
echo $errmsg
}
# test if we have two arguments on the command line
if [ $# != 2 ]
then
usage
exit
fi
# test if file one exists and send an additional error message
# to usage if not found
if [ ! -f $1 ]
then
errmsg=${1}": File Not Found"
usage
exit
fi
# same for file two
if [ ! -f $2 ]
then
errmsg=${2}": File Not Found"
usage
exit
fi
# we are ok at this point so continue processing here
Comparando números
-eq Igual
!= Diferente
-gt Maior
-lt Menor
Mais comparações
-o Ou
-d Se for um diretório
-e Se existir
-z Se estiver vazio
-f Se contiver texto
-o Se o usuário for o dono
-r Se o arquivo pode ser lido
-w Se o arquivo pode ser alterado
-x Se o arquivo pode ser executado
Criando uma pasta rapidinho
[ -d dir ] || mkdir dir ; cd dir
[-n] STRING
Tamanho da String é diferente de zero
-z STRING
Tamanho da String é zero
STRING1 = STRING2
Strings são iguais
STRING1 != STRING2
Strings não são iguais
NUMERO1 -eq NUMERO2
NUMERO1 igual a NUMERO2
NUMERO1 -ge NUMERO2
NUMERO1 igual e/ou mair que NUMERO2
NUMERO1 -gt NUMERO2
NUMERO1 maior que NUMERO2
NUMERO1 -le NUMERO2
NUMERO1 menor e/ou igual a NUMERO2
NUMERO1 -lt NUMERO2
NUMERO1 menor que NUMERO2
NUMERO1 -ne NUMERO2
NUMERO1 diferente de NUMERO2
if [ "texto" = "texto" ]; then
echo "o texto é igual";
fi
if [ 1 -gt 5 ]; then
echo "1 é maior que 5";
fi
if [ "a" = "3" ] || [ "a" = "b" ]; then
echo "a não é igual a 3 ou c";
elif [ "a" = "c" ] || [ "a" = "d" ]; then
echo "a não é igual a c ou d";
else
echo "A é diferente de 3,c,b,d";
fi
Testando se um arquivo está vazio
[ -s arquivo ] && echo nao vazio || echo arquivo vazio
Permitindo somente uma instância de um script
Às vezes você tem um script e quer que ele não possa ser executado
mais de uma vez ao mesmo tempo. A solução
LOCK_FILE=/tmp/.lock
(set -C; : > $LOCK_FILE) 2> /dev/null
if [ $? != "0" ]; then
echo "Lock File exists - exiting"
exit 1
fi
# Do useful stuff
trap 'rm $LOCK_FILE' EXIT
Permitindo a execução somente pelo root
Há scripts que só podem ser executados pelo root
para verificar faça
# Check the script is being run by root
if [ `id -u` != "0" ]; then
echo "This script must be run as root"
exit 1
fi
#!/bin/bash
CONTADOR=0
while $CONTADOR -lt 10 ; do
echo "Contador em: $CONTADOR";
let CONTADOR=CONTADOR+1;
done
enquanto $CONTADOR menor que 10 ; faça
imprima "Contador em: $CONTADOR";
imcremente 1 no $CONTADOR;
feito
Estruturas
case $1 in
parametro1) comando1 ; comando2 ;;
parametro2) comando3 ; comando4 ;;
*) echo "Você tem de entrar com um parâmetro válido" ;;
esac
if [ -z $1 ]; then
echo "Você tem de entrar com um parâmetro válido"
exit
elif [ $1 = "parametro1" ]; then
comando1
comando2
elif [ $1 = "parametro2" ]; then
comando3
comando4
else
echo "Você tem de entrar com um parâmetro válido"
fi
for i in *
do
cp $i $i.backup
mv $i.backup /usr/backup
done
for original in *; do
resultado=`echo $original |
tr '[:upper:]' '[:lower:]'`
if [ ! -e $resultado ]; then
mv $original $resultado
fi
done
O comando test
Os colchetes são um aliás para o comando test
[[ string =~ regex ]]
# testa se o usuário digitou um parâmetro "$1"
if [ -z "$1" ]; then
echo ' uso: matar programa '
exit
fi
Um jeito direferente de usar o comando mkdir
mkdir -p teste/{docs/{img/{fotos/,wallpapers/,icons/},man/,textos/{bv/,teste/}}}
Exemplos
ping -c 2 www.google.com > &> /dev/null &&
echo "google respondeu" || echo "rost fora do ar"
google respondeu
Somando números de 1 a 100
seq -s+ 100 | bc
Controle de fluxo
#!/bin/bash
if [ -e $linux ]
then
echo 'A variável $linux existe.'
else
echo 'A variável $linux não existe.'
fi
Exemplo usando operadores
#!/bin/bash
a=1
b=2
if [ $a -lt $b ]
then
echo '$a é menor que $b!'
elif [ $a -gt $b ]
then
echo '$a é maior que $b!'
elif [ $a -eq $b ]
then
echo '$a é igual a $b!'
fi
====================
Gerador de números aleatórios
====================
echo $((RANDOM%Limite))
Onde limite+1 é até que número o shell deverá gerar números aleatórios
E se quiser armazenar o valor gerado:
Valor=$((RANDOM%Limite))
$((RANDOM%5+1))
gera números de 1 a 5
===================================
Para gerar um número aleatório entre -10 e 10
number=$(($((RANDOM%21))-10))
====================
Fluxo com o for
====================
for i in *
do
cp $i $i.backup
mv $i.backup /usr/backup
done
====================
#!/bin/bash
if [ -e $linux ]
then
echo 'A variável $linux existe.'
else
echo 'A variável $linux não existe.'
fi
Exemplo usando operadores
#!/bin/bash
a=1
b=2
if [ $a -lt $b ]
then
echo '$a é menor que $b!'
elif [ $a -gt $b ]
then
echo '$a é maior que $b!'
elif [ $a -eq $b ]
then
echo '$a é igual a $b!'
fi
=====================
Fluxo com while
=====================
O while testa continuamente uma expressão, até que ela se torne falsa. Exemplo:
variavel="valor"
while [ $variavel = "valor" ]; do
comando1
comando2
done
Ufa! Como você viu tem coisa prá chuchu, e como eu te disse no início,
o nosso if é muito mais poderoso que o dos outros. Vamos ver em uns
exemplos como isso tudo funciona, primeiramente testaremos a
existência de um diretório:
Exemplos:
if test -d lmb
then
cd lmb
else
mkdir lmb
cd lmb
fi
No exemplo, testei se existia um diretório lmb definido, caso negativo
(else), ele seria criado. Já sei, você vai criticar a minha lógica
dizendo que o script não está otimizado. Eu sei, mas queria que você o
entendesse assim, para então poder usar o ponto-de-espantação (!) como
um negador do test. Veja só:
if test ! -d lmb
then
mkdir lmb
fi
cd lmb
e utilizando a nova sintaxe, vamos fazê-lo assim:
Isso também poderia ser escrito da seguinte maneira:
Ou ainda retirando a negação (!):
Neste caso, se o cd fosse mal sucedido, seria criado o diretório lmb
mas não seria feito o cd para dentro dele. Para executarmos mais de um
comando desta forma, é necessário fazermos um grupamento de comandos,
e isso se consegue com o uso de chaves ({ }). Veja como seria o
correto:
cd lmb ||
{
mkdir lmb
cd lmb
}
Ainda não está legal, porque caso o diretório não exista, o cd dará a
mensagem de erro correspondente. Então devemos fazer:
cd lmb 2> /dev/null ||
{
mkdir lmb
cd lmb
}
==============================================
Para pegar uma variável digitada pelo usuário
==============================================
read -p "digite o seu nome: " nome
Combinando comandos
O arquivo de configuração do estilos do firefox (para páginas) é nomeado como: userContent.css para buscalo uso o parâmetro '-iname' do find, mas às vezes mantenho cópias em outros locais, para evitar erros busco em minha pasta pessoal por uma pasta que tem um número aleatório no começo e no final a palavra default.
cp $(find ~/ -iname usercontent.css | grep default) /home/sergio/Desktop/
Arrays
O que você quer fazer? O BASH não oferece funções para tratar arrays.
Mas um array é algo assim:
$ array=( A B C D )
$ echo ${array[0]}
A
$ echo ${array[1]}
B
$ echo ${array[@]}
A B C D
VAR=($(ls *.html)) --> gera um array
echo ${VAR[0]}
=====================================
Script para criar 100 arquivos txt
=====================================
#!/bin/bash
for ((i=1; i<=100; i++)); {
touch arquivo${i}.txt
echo "arquivo${i}.txt" >> arquivo${i}.txt
}
============================================================
Grupos de comandos Expansão de strings e nomes de arquivos
============================================================
O Bash permite agrupar comandos, que desse modo são executados como uma única
unidade. Podemos agrupar os comandos de duas formas:
1) Agrupamento por parênteses, "( )": Comandos colocados entre parênteses e
separados por ponto-e-vírgula, ";", são agrupados e executados serialmente
invocando um subshell. Exemplo:
# (ls; du; find -name *.txt)
2) Agrupados por chaves, "{ }":
Comandos colocados entre chaves e separados por ponto-e—vírgula, ";", são
agrupados e executados serialmente no shell corrente. Exemplo:
# {ls; du; find -name *.txt}
Você deve estar pensando: "Para que eu agruparia meus comandos? Para deixá-los mais bonitos?" Não!
A vantagem de vários comandos agrupados pode ser vista quando precisamos
desviar a saída desses comandos. Imagine que você precise fazer um script para
executar vários comandos e obter a saída de erros de cada comando colocado no
script. Seria assim:
...
comando1 2>erros.txt
comando2 2>>erros.txt
comando3 2>>erros.txt
comando4 2>>erros.txt
...
Com o agrupamento isso fica mais fácil e simples:
...
(
comando1 ;
comando2 ;
comando3 ;
comando4 ;
) 2>erros.txt
...
Observe que no primeiro exemplo desviamos o erro para cada comando e no segundo
exemplo o desvio foi feito para todos os comandos em uma única vez.
Se esse exemplo fosse passado para a linha de comando ficaria desta forma: exemplo 1:
# comando1 2>erros.txt; comando2 2>>erros.txt ; comando3 2>>erros.txt comando4 >>erros.txt
exemplo 2:
#(comando1;comando2;comando3;comando4;) 2> erros.txt
Você concorda que, com agrupamento, a linha de comando fica até mais legível!
Agora vamos imaginar que você precise tratar a saída de vários comandos, por
exemplo, alterar de minúsculo para maiúsculo. Você poderia escrever assim:
# cat /etc/hosts | tr a-z A-Z > saida.txt ;
cat /etc/resolv.conf |tr a-z A-Z >>saida.txt ;
cat /etc/sysconfig/network | tr a-z A-Z >>saida.txt
Mas o ideal seria:
# (cat /etc/hosts ; cat /etc/resolv.conf ;
cat /etc/sysconfig/network; )| tr a-z A-Z >>saida.txt
No segundo exemplo, além de ficar mais legível, o comando "tr" é executado uma
única vez, já no primeiro exemplo cada um dos comandos será executado.
A diferença entre os grupos criados com parênteses, "( )", ou os criados com
chaves, "{ }", pode ser vista no comando abaixo:
# VAR="ANTES";(VAR="DEPOIS";VAR="ADIANTE";); echo $VAR
ANTES
# VAR="ANTES";{VAR="DEPOIS";VAR="ADIANTE";}; echo $VAR
ADIANTE
Observe que no exemplo escrito com parênteses a variável VAR retornou ao mesmo
valor que fora atribuído antes de executar o grupo de comandos. Isso se deve ao
fato de que os comandos são executados em subshell. Já no exemplo escrito com
chaves a variável VAR retornou ao último valor que fora atribuído, porque
grupos feitos com chaves são executados no shell corrente.
Expansão de strings
Expansão de strings é um mecanismo que combina uma expressão inicial com um
conjunto de caracteres. Exemplo:
#echo a{1,2,3}
a1 a2 a3
As combinações são feitas entre os elementos que estão entre as chaves
separados por vírgula, da esquerda para a direita.
Podemos combinar mais que um conjunto de caracteres simultaneamente:
# echo a{1,2,3}b{1,2,3}
a1b1 a1b2 a1b3 a2b1 a2b2 a2b3 a3b1 a3b2 a3b3
Combinar dois conjuntos separadamente também é possível, basta colocar os
conjuntos entre chaves e separá-los por vírgula.
# echo {a{1,2,3},b{1,2,3}}
a1 a2 a3 b1 b2 b3
A grande vantagem da expansão está na expansão de nomes de arquivos, que é
utilizada em comandos que recebem como parâmetro um ou mais nome de arquivos.
Exemplo:
# ls /dev/hda
| |––> Este é o parâmetro do ls que deve ser um diretório ou um arquivo Imagine
que você queira listar todos os arquivos do diretório /dev que inicie com hda e
termine com 1, 2 ou 3.
# ls /dev/hda{1,2,3}
/dev/hda1 /dev/hda2 /dev/hda3
Podemos combinar dois conjuntos também:
# ls /dev/{hda{1,2,3},hdb{1,2,3}}
/dev/hda1 /dev/hdb1
/dev/hda2 /dev/hdb2
/dev/hda3 /dev/hdb3
Adicionar metacaracteres também é possível:
# ls /dev/{hd?{1,2,3}}
/dev/hda1 /dev/hdb1 /dev/hdc1 /dev/hdd1
/dev/hda2 /dev/hdb2 /dev/hdc2 /dev/hdd2
/dev/hda3 /dev/hdb3 /dev/hdc3 /dev/hdd3
Os metacaracteres suportados em expansão são:
* — Um ou mais caracteres
# ls /dev/{hd{a,b,c}*}
/dev/hda1 /dev/hdb1 /dev/hdc1
/dev/hda11 /dev/hdb11 /dev/hdc11
/dev/hda2 /dev/hdb2 /dev/hdc2
/dev/hda3 /dev/hdb3 /dev/hdc3
? — Exatamente um caractere
# ls /dev/{hd{a,b,c}?}
/dev/hda1 /dev/hdb1 /dev/hdc1
/dev/hda2 /dev/hdb2 /dev/hdc2
/dev/hda3 /dev/hdb3 /dev/hdc3
[abc] — Combina com a, b ou c
# ls /dev/{hd[abc]{1,2,3}}
/dev/hda1 /dev/hdb1 /dev/hdc1
/dev/hda2 /dev/hdb2 /dev/hdc2
/dev/hda3 /dev/hdb3 /dev/hdc3
[a-z] — Combina o range de "a" a "z"
# ls /dev/{hd[a-c]{1,2,3}}
/dev/hda1 /dev/hdb1 /dev/hdc1
/dev/hda2 /dev/hdb2 /dev/hdc2
/dev/hda3 /dev/hdb3 /dev/hdc3
[!a-z] — Não combina o range de "a" a "z"
# ls /dev/{hd[!a-c]{1,2,3}}
/dev/hdd1 /dev/hde1 /dev/hdf1
/dev/hdd2 /dev/hde2 /dev/hdf2
/dev/hdd3 /dev/hde3 /dev/hdf3
Espero ter contribuído mais um pouco para o aprendizado dos leitores.
Até a próxima edição!
Fazendo testes antes de executar um script
fonte: http://br.geocities.com/cesarakg/tips-shell-programming.html
Testando argumentos de linha de comando e modo de usar
Quando você escreve um shell script, os argumentos são normalmente necessários para que o script funcione corretamente. Para garantir que os argumentos façam algum sentido, é geralmente necessário validar os mesmos.
Testar para ver se há argumentos suficientes é geralmente o método mais fácil de validação. por exemplo, se você criou um script shell que pede dois nomes de arquivos para operar, teste a existência de dois argumentos na linha de comando. para fazer isto no Bourne e no Korn shell, verifique o valor de $# -- uma variável que contém a contagem de argumentos, além do próprio comando. É também uma boa pratica incluir uma mensagem que detalhe as razões por que o comando falhou. Isto é criado em uma função usage.
O script twofiles abaixo, testa se há dois argumentos na linha de comando:
#!/bin/ksh
# twofile script handles two files named on the command line
# a usage function to display help for the hapless user
usage ()
{
echo "twofiles"
echo "usage: twofiles file1 file2"
echo "Processes two files"
}
# test if we have two arguments on the command line
if [ $# != 2 ]
then
usage
exit
fi
Uma prática mais segura é validar o máximo que você puder antes de executar alguma coisa. A seguinte versão de twofiles verifica a contagem de argumentos e testa os dois arquivos. Se o arquivo 1 não existe ( if [ ! -f $1 ]) uma mensagem de erro é configurada, uma mensagem de uso é apresentada, e o programa termina. O mesmo é feito para o arquivo 2:
#!/bin/ksh
# twofiles script handles two files named on the command line
# a usage function to display help for the hapless user
# plus an additional error message if it has been filled in
usage ()
{
echo "twofiles"
echo "usage: twofiles file1 file2"
echo "Processes two files"
echo " "
echo $errmsg
}
# test if we have two arguments on the command line
if [ $# != 2 ]
then
usage
exit
fi
# test if file one exists and send an additional error message
# to usage if not found
if [ ! -f $1 ]
then
errmsg=${1}": File Not Found"
usage
exit
fi
# same for file two
if [ ! -f $2 ]
then
errmsg=${2}": File Not Found"
usage
exit
fi
# we are ok at this point so continue processing here
Note que no Korn shell você pode usar a sintaxe de teste de colchetes duplos, que é mais rápida. O colchete simples na verdade chama um programa test para testar os valores, enquanto que com o colchete duplo o teste é implementado no Korn shell e não precisa chamar um programa separado.
O teste de colchete duplo não funciona no Bourne shell:
if [[ $# != 2 ]]
ou
if [[ ! -f $1 ]]
ou
if [[ ! -f $2 ]]
Esta validação pode evitar erros posteriores na lógica do programa quando subitamente percebe-se que um arquivo está faltando. Considere isto como uma boa prática de programação.
Atalhos do bash
ATALHOS DO BASH
Ctrl + Alt + BackSpace : reinicia o X
Ctrl + Alt + Del : reinicia o sistema em modo texto
Ctrl + Alt + F''x'' : muda o shell (F1 – F6 (texto), F7 (gráfico))
Alt + F''x'' : alterna o shell (modo texto)
Alt + B : move o cursor do console para a palavra anterior
Alt + F : move o cursor do console para a palavra seguinte
Ctrl + A : vai para o início da linha
Ctrl + E : vai para o fim da linha
Ctrl + C : pára o comando
Ctrl + D : logout
Ctrl + W : apaga do cursor até o início da palavra
Ctrl + U : apaga do cursor até o início da linha
Ctrl + K : apaga do cursor até o fim da linha
Ctrl + L : clear
Ctrl + R : busca incremental no hitórico de comandos
Ctrl + T : inverte caractere sob o cursor com o anterior
Ctrl + Y : re-inserir o último texto apagado
Ctrl + Z: colocar processo em background
Shift + Page(UP/DOWN) : navega pelo shell
!''x'': repete o último comando (onde ''x'' é o comando a ser chamado – Exemplo: !mount)
TAB : autocompletar
Criando uma árvore de diretórios com um único comando
mkdir -p {.wiki/,.vim/{plugin/,syntax},docs/{img/{fotos/,wallpapers/,icons},textos/{artigos/,man/{shell/,vim/,}}}}
No comando acima são criadas três pastas
.wiki (oculta)
.vim - contendo as subpastas plugin e syntax
docs contendo: img (fotos wallpapers e icons) textos contendo (argigos) e (man (shell e vim)
Como guardar variáveis em arquivos
use . /caminho/para/arquivo
Note o espaço entre o ponto e a barra
Usando cores
Fonte: http://www.vivaolinux.com.br/artigos/impressora.php?codigo=1908
echo -e "Viva o �33[01;32mLinux�33[01;37m"
Observem no exemplo os trechos em negrito e reparem que são eles um dos temas do nosso artigo. Tentarei explicar o que vemos:
* "�33": ainda não consegui encontrar o real motivo de usar isto, mas é obrigatório para usar as cores, se trocar por outra coisa dará tudo errado;
* "01"( estilo): significa que nosso texto será em negrito (bold);
* "32m" (cor do texto): 32 representa a cor vermelha e o "m" indica o fim da expressão e após ele você já poderá incluir o texto que bem desejar;
Meio complicado ainda né!? Mas vai abaixo os dados que certamente irão ajudar a se organizar:
Estilos |
Cores de texto |
Cores de fundo |
00: Nenhum |
30: Preto |
40: Preto |
01: Negrito |
31: Vermelho |
41: Vermelho |
04: Sublinhado |
32: Verde |
42: Verde |
05: Piscante |
33: Amarelo |
43: Amarelo |
07: Reverso |
34: Azul |
44: Azul |
08: Oculto |
35: Magenta (Rosa) |
45: Magenta (Rosa) |
|
36: Ciano (Azul Ciano) |
46: Ciano (Azul Ciano) |
|
37: Branco |
47: Branco |
Filtrando linhas de um arquivo
Re: [shell-script] Filtrar linhas no arquivo texto
Acho que um sed + ER fica legal:
$ cat test
documento_0012526A.odt
documento_0035555A.odt
documento_0054443A.odt
documento_0022222A.odt
documento_0034344A.odt
documento_0055555A.odt
$ sed 's/^documento_(.*).odt$/1/' test
0012526A
0035555A
0054443A
0022222A
0034344A
0055555A
Named Pipes
Fonte: http://www.dicas-l.com.br/cantinhodoshell/cantinhodoshell_20070520.php
Autor: Júlio César Neves
$ cat <(ls -l)
Resultará no comando ls -l executado em um subshell como é normal, porém redirecionará a saída para um named pipe temporário, que o Shell cria, nomeia e depois remove. Então o cat terá um nome de arquivo válido para ler (que será este named pipe e cujo dispositivo lógico associado é /dev/fd/63), e teremos a mesma saída que a gerada pela listagem do ls -l, porém dando um ou mais passos que o usual.
Veja mais...
veja também
Comments (0)
You don't have permission to comment on this page.