As crases permitem atribuir a saída de um comando do shell a uma variável. O comando todo deve estar entre crases, por exemplo:
dia=`date`
echo "A data é $dia."
Veja um outro exemplo de uso de script na criação de arquivos:
#!/bin/bash
# Copiar a listagens de um diretório para
# arquivos únicos de acordo com data e hora
arq=`date +%d%m%y%H%M` # Formatação de data e hora
ls -la ~>log.$arq # Redireciona pra um arquivo, um > sobreescreve arquivos, dois >> adiciona no mesmo
Dessa forma ele criará um arquivo de log cuja extensão é a data do qual o arquivo foi criado.
O redirecionamento de saída mais comum é enviar a saída de um comando para um arquivo. Para isso use o símbolo >, como por exemplo comando > arquivosaida
.
Caso queira acrescentar a saída e um comando a um arquivo em vez de sobreescrevê-lo, use o símbolo duplo, tipo comando >> arquivosaida
.
Digite esses comandos:
ls -l>arq.txt
date>>arq.txt
Em vez de redirecionar a saída de um comando para um arquivo, é possível tomar o conteúdo de um arquivo e redirecioná-lo para o comando. Para isso use o símbolo <, como comando < arquivoentrada
.
O comando wc produz contagem de texto do arquivo. Por padrão mostra três valores, nessa ordem: Nº de linhas no texto, Nº de palavras e Nº de bytes. Veja um exemplo onde o wc recebe o arquivo criado de parâmetro:
wc<arq.txt
Entrar com as informações pelo terminal também é possível, com este método é possível especificar os dados para redirecionamento na linha de comandm em vez de um arquivo. O símbolo de redirecionamento de entrada inline é <<. Você também deve especificar um marcador de texto (que pode ser qualquer palavra) que delineie o início e o fim dos dados usados para entrada, por exemplo, podemos digitar no shell isso:
wc<<EOF
Digite uma ou mais frases e termine com o marcador para encerrar
EOF
É possível realizar cálculos matemáticos diretamente no bash, e atribuir o resultado de uma operação a uma variável. Para isso, englobe a equação usando um cifrão e colchetes, por exemplo:
var1=$[2 + 6]
echo $var1
var2=$[$var1 * 2]
echo $var2
Num script sh, podemos fazer assim:
#!/bin/bash
var1=10
var2=5
var3=2
var4=$[$var1 * ($var2 - $var3)]
echo "O resultado do cálculo é $var4."
PS: Todos os operadores podem ser usados, só não esqueça da ordem das operações, como podem ver:
Ordem | Operador |
---|---|
1 | () |
2 | ** |
3 | * / // % |
4 | + - |
Porém, há um problema em realizar cálculos com o shell bash: Seus operadores matemáticos só suportam aritmética de números inteiros. Por exemplo:
#!/bin/bash
var1=9
var2=2
var3=$[$var1 / $var2]
echo "Resultado: $var3."
O resultado deveria ser 4,5, mas o shell retorna 4.
A calculadora do bash é na verdade uma linguagem de programação que permite executar expressões de ponto flutuante no terminal. Ela reconhece números inteiros e ponto flutuantes, variáveis simples e arrays, comentários estilo linguagem C ("/* */"), expressões, declarações condicionais if-then e funções.
Para acessar a calculadora do bash no shell digite o comando bc
. Você entrará no modo interativo da calculadora. Digite então as expressões que deseja calcular e pressione enter. Para sair da calculadora digite quit
.
Digite bc
(podendo omitir a mensagem digitando bc -q
) e alguns cálculos, essa ordem:
2 + 3
3 * (2 + 5)
sqrt(81)
quit
A aritmética de ponto flutuante na calculadora bc é controlada pela variável especial scale
. Você configura seu valor para o número desejado de casas decimais que necessita nos resultados. Por padrão, a variável scale vem definida com o valor zero.
Dentro do bc, digitando algo como 2 / 4
ele retorna um valor inteiro (0), então para fazermos um cálculo com números reais, fazemos assim:
scale=2 # Número de casas decimais
2 / 4
Com variáveis:
scale=6
a=4
b=6
a / b
Para usar a bc em um script, use a crase para rodar o comando e atribuir seu valor a uma variável, por exemplo:
var=`echo "scale=2; 2 / 5" | bc`
echo "Resultado $var."
Criando um script para cálculos simples:
#!/bin/bash
var1=100
var2=30
var3=`echo "scale=4; $var1 / $var2" | bc`
echo "Resultado $var3."
Essa técnica funciona bem para cálculos simples, mas em cálculos mais complexos é recomendável usar a técnica do redirecionamento de entrada inline. Por exemplo:
#!/bin/bash
var1=6
var2=5
var3=4
var4=`bc<<EOF
scale=4
a1=($var1 * $var2)
b1=($var3 + $var1)
a1 + b1
EOF`
# Não esquecer as crases acima
echo "Resultado $var4."
Cada comando que roda no shell usa um valor de status de saída para indicar ao shell que o processamento terminou. O status de saída é um inteiro entre 0 e 255. A variável especial $?
armazena o valor do status de saída do último comando executado. O status de saída de um comando executado com sucesso é zero, se houver algum erro, será um inteiro positivo.
Esses são alguns significados:
Código | Significado |
---|---|
0 | Código Completado com Sucesso |
1 | Erro Geral Desconhecido |
126 | O Comando não Pode ser Executado (Permissões) |
127 | Comando não ENcontrado |
130 | Comando Finalizado com Ctrl C |
Digite esses comandos:
ls
echo $? # Retorna 0
lxy # Esse comando não existe
echo $? # Retorna 127
Por padrão, seu shell script finaliza com o status de saída do último comando executado no script. É possível alterar esse comportamento para retornar seu próprio código de status. O comando exit permite especificar um status de saída quando o script finaliza.
Veja esse exemplo de script:
#!/bin/bash
var1=10
var2=2
var3=$[$var1 * $var2]
echo $var3
exit 6 # Retorna o código de saída 6
PS: Você também pode usar variáveis com valor numérico como parâmetro do comando exit, por exemplo exit $var3
.
Execute o script com o código acima, depois dê o comando echo $?
, veremos que ele retorna o código 6 ao invés do 0. Podemos colocar qualquer número entre 0 e 255.
Como sabemos, em programação existem comandos estruturados para definirmos decisões em programas, o mais comum é o if e else, que no Shell Scripting é um pouco diferente das linguagens de programação.
A declaração if do Shell Bash executa o comando definido na linha if. Se o status de saída do comando for zero, os comandos listados após a seção then serão executados. Caso contrário, esses comandos serão ignorados.
Exemplo de condicional simples num script:
if cd /
then
echo "Diretório raiz Encontrado!"
fi
O condicional compost permite executar um bloco de código caso o comando testado retorne código de status zero, e outro bloco de código caso retorne status diferente de zero.
Veja um exemplo com else:
if ls ~/teste
then
echo "Diretório teste Encontrado!"
else
echo "Diretório teste não-Encontrado!"
fi
PS: Podemos colocar o then na mesma linha, nesse caso separe por um ponto-e-vírgula, assim:
if ls ~/teste; then
echo "Diretório teste Encontrado!"
else
echo "Diretório teste não-Encontrado!"
fi
Isso é bom para verificarmos se um diretório ou arquivo existe ou não.
Às vezes é necessário verificar várias situações relacionadas em seu script. Em vez de ter de escrever declarações if-then separadas, você pode usar uma versão alternativa da seção else, chamada elif. O elif continua uma seção else com outra declaração if-then. O shell bash executará as declarações if em ordem, e apenas a primeira que retornar status de saída 0 terá a seção then correspondente executada.
Veja um exemplo de uso:
var1="eu"
var2="user"
if ls /home/$var1; then
echo "Diretório do usuário $var1 encontrado!"
elif ls /home/$var2; then
echo "Diretório do usuário $var2 encontrado!"
else
echo "Nenhum dos diretórios foram encontrados!"
fi
A declaração if-then não consegue avaliar nenhuma condição que não seja o código de status de saída de um comando. Porém, é possível avaliar outras condições usando o comando test em uma declara~ao if-then. O comando teste avalia uma condição, e se ela retornar true, o comando teste retorna código de saída igual a zero, caso contrário, retorna status de saída igual a 1.
O shell bash fornece uma maneira alternativa de declarar o comando test com o if-then. Os colchetes definem a condição usada pelo test, deve haver espaços antes e depois da condição.
O comando test pode avaliar três classes de condições: Comparações numéricas, de strings e de arquivos.
Esses são as opções de verificação de números em Bash:
Comando | Significado |
---|---|
-eq | Igual |
-ne | Diferente |
-lt | Menor que |
-le | Menor que ou igual |
-gt | Maior que |
-ge | Maior que ou igual |
Eles avaliam tanto números quanto variáveis. Mas apenas números inteiros.
Veja esse exemplo de código aqui:
var1=10
var2=15
if [ $var1 -gt 8 ]; then
echo "A variável de valor $var1 é maior do que 8"
fi
if [ $var1 -eq $var2 ]; then
echo "Os valores são iguais!"
else
echo "Os valores são diferentes!"
fi
Tente alterar os números acima.
PS: Caso faça comparações envolvendo alguma operação como o resto, coloque o cálculo entre o cifrão e colchetes, como uma conta, por exemplo:
#!/bin/bash
read -p "Digite um número: " num
if [ $[$num % 2] -eq 0 ]; then
echo "O número $num é par!"
else
echo "O número $num é ímpar!"
fi
O comando test também permite realizar comparações entre valores de strings. Vejamos na tabela a seguir os operadores de comparação e seus significados.
As comparações de string com test são essas:
Comparação | Descrição |
---|---|
= | Verifica se as strings são iguais (atenção que é um só). |
!= | Verifica se as strings são diferentes |
< | Verifica se a string é "menor" que a outra |
> | Verifica se a string é "maior" que a outra |
-n | Verifica se a string tem comprimento maior que zero. |
-z | Verifica se a string tem comprimento zero. |
PS: Diferente das outras linguagens de programação, a comparação de igual acontece com apenas um =, ao invés de dois. Como as atribuições são feitas "grudadas", elas se diferenciam do igual.
Veja um exemplo simples de comparação:
nome=eu
if [ $USER = $nome ]; then
echo "Olá $nome."
fi
Outro exemplo:
#!/bin/bash
var1=abacate
var2=''
if [ -n $var1 ]; then
echo "Variável não está vazia, contém o valor $var1!"
else
echo "Variável está vazia!"
fi
# Outra condição:
if [ -z $var2 ]; then
echo "Variável está vazia!"
else
echo "Variável não está vazia!"
fi
As comparações de arquivos são o tipo de comparações mais poderosas e mais usadas em Shell Scripting. O comando test permite testar o status de arquivos e diretórios no sistema de arquivos Linux, conforme a tabela a seguir:
Comando | Significado |
---|---|
-d arquivo | Verifica se o arquivo existe e se é um diretório |
-e arquivo | Verifica se o arquivo existe |
-f arquivo | Verifica se o arquivo existe e se é um arquivo |
-r arquivo | Verifica se o arquivo existe e se possui permissão de leitura para o usuário atual |
-s arquivo | Verifica se o arquivo existe e não está vazio |
-w arquivo | Verifica se o arquivo existe e tem permissão de escrita |
-x arquivo | Verifica se o arquivo existe e tem permissão de execução |
-O arquivo | Verifica se o arquivo existe e é propriedade do usuário atual |
-G arquivo | Verifica se o arquivo existe e seu grupo padrão é o mesmo do usuário atual |
arq1 -nt arq2 | Verifica se o arquivo arq1 é mais novo que arq2 |
arq1 -ot arq2 | Verifica se o arquivo arq1 é mais antigo que arq2 |
Veja um exemplo de uso:
#!/bin/bash
# Verifica se o diretório HOME do usuário
# existe e mostra seu conteúdo:
if [ -d $HOME ]; then
echo "Seu diretório home existe e o conteúdo é: "
cd $HOME
ls -l
else
echo "Diretório não encontrado!"
fi
Outro exemplo:
#!/bin/bash
# Verifica se o objeto é um arquivo
if [ -e $HOME ]; then
echo "O objeto existe, vamos ver se é arquivo ou diretório."
if [ -f $HOME ]; then
echo "É um arquivo!"
else
echo "É um diretório!"
fi
else
echo "Objeto não encontrado!"
fi
PS: Note que temos acima um if aninhado.