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
Essa apostila está em formato *.ps no kurumin linux use o comando ps2pdf para gerar um pdf.
ps2pdf aposhell.ps
^ ---> 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
$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]'/*{{{*//*}}}*/
#!/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
-eq Igual
!= Diferente
-gt Maior
-lt Menor
-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
[ -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
[ -s arquivo ] && echo nao vazio || echo arquivo vazio
À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
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
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
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/}}}
ping -c 2 www.google.com > &> /dev/null && echo "google respondeu" || echo "rost fora do ar" google respondeu
seq -s+ 100 | bc
#!/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:
! -d lmb && mkdir lmb
cd dir
Ou ainda retirando a negação (!):
-d lmb || mkdir lmb
cd dir
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
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/
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 }
============================================================
============================================================
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!
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 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
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)
use . /caminho/para/arquivo Note o espaço entre o ponto e a barra
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 |
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
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.