Introdução

Neste post, vamos ver algumas como utilizar a Bash como uma linguagem de programação. Ou seja, como criar scripts para correr comandos mais complexos do que aqueles que normalmente usamos em linha de comando.

Variáveis

A Bash permite trabalhar com variáveis de forma bastante flexível. ($help echo dá informação sobre o comando echo)

[pf@deti-cte ~]$ x=4
[pf@deti-cte ~]$ echo x
x
[pf@deti-cte ~]$ echo $x
4
[pf@deti-cte ~]$ echo ${x}
4

Note-se que é preciso usar o $ (com ou sem chavetas) para obter “o valor de x”.

É possível realizar operações aritméticas com a Bash-

[pf@deti-cte ~]$ y=2
[pf@deti-cte ~]$ echo $((x+y))
6

Podemos apresentar o que se chama “saída formatada” com o comando printf.

pf@deti-cte ~]$ printf "O valor de x é %d.\n" $x
O valor de x é 4.
[pf@deti-cte ~]$ x=6
[pf@deti-cte ~]$ printf "O valor de x é %d.\n" $x
O valor de x é 6.

Iterações

Ciclo for

[pf@deti-cte ~]$ seq 1 6
1
2
3
4
5
6

O comando for permite-nos iterar sobre uma sequência de valores, executando um comando para cada um dos elementos da sequência.

[pf@deti-cte ~]$ for n in $(seq 1 6); do echo $n; done;
1
2
3
4
5
6

Vamos ver o help do for para perceber a linha acima:

[pf@deti-cte ~]$ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

O nome da variável é n e ela vai ter os valores definidos a seguir ao termo in. O termo a seguir ao in, neste caso, tem a forma $(comando). Em Bash, $(comando) significa “executar o comando e devolver o resultado”. Neste caso, $(seq 1 6) vai fazer correr o comando seq 1 6 que gera os número 1, 2, …, 6 e devolver esse resultado, que é assim a sequência de valores que a variável n vai assumir no ciclo for. Em vez do dólar $, pode usar-se “pelicas para trás”: `comando` é a mesma coisa que $(comando).

[pf@deti-cte ~]$ for n in `seq 1 6`; do echo $n; done;
1
2
3
4
5
6
[pf@deti-cte ~]$ for n in seq 1 6; do echo $n; done;
seq
1
6

(Explique o resultado deste último comando…)

Ciclo while

while: while COMMANDS; do COMMANDS; done
    Execute commands as long as a test succeeds.

    Expand and execute COMMANDS as long as the final command in the
    'while' COMMANDS has an exit status of zero.

Um exemplo de ciclo while em Bash:

[pf@deti-cte ~]$ x=1;
[pf@deti-cte ~]$ while [ $x -le 4 ]; do
> echo "Este é o número $x";
> x=$(($x+1));
> done;
Este é o número 1
Este é o número 2
Este é o número 3
Este é o número 4

Condicionais (if)

Referência:

Tal como noutras linguagens de programação, o comando if permite executar uma instrução condicionalmente. O uso do if é apresentado a seguir, a propósito das shell scripts.

Shell scripts

Um shell script é um ficheiro de texto com um conjunto de instruções (comandos). Normalmente, estes ficheiros têm uma extensão .sh e a primeira linha é #!/bin/bash. Esta primeira linha é uma indicação que o programa deve user a Bash como shell para interpretar os comandos.

As linhas que comecem por # num ficheiro script são comentários. O exemplo seguinte apresenta um script de shell para calcular os números da sequência de Fibonacci até 50.

#!/bin/bash
# Shows fibonoacci numbers up to 50
a=0
b=1
while (( $b < 50 )); do
    echo "$b"
    olda=$a
    a=$b
    b=$(($olda + $b))
done

Supondo que este ficheiro está guardado com o nome fibonacci50.sh, correr o script é feito com o comando:

[pf@deti-cte ~]$ ll
total 4
-rw-r--r--. 1 pf users   0 Apr  1 22:55 compras.txt
drwxr-xr-x. 2 pf users  24 Apr  1 22:55 Documents
-rwx------. 1 pf users 130 Apr  2 01:38 fibonacci50.sh
[pf@deti-cte ~]$ ./fibonacci50.sh
1
1
2
3
5
8
13
21
34

A forma ./fibonacci50.sh significa: correr o ficheiro fibonacci50.sh que se encontra no directório corrente ./.

Argumentos

Um ficheiro script pode ser lançado com argumentos. Dentro do script, os argumentos são representados por $n, com n=0,1,2,… $0 é o próprio nome do script, $1 o primeiro argumento e por aí adiante.

O ficheiro anterior adaptado para ter um valor qualquer de máximo para o cálculo da sequência de Fibonacci, que é passado através da linha de comando, ficaria:

#!/bin/bash
# Shows fibonoacci numbers up to the first command line argument ($1)
echo $0

if [ -z "$1" ]
  then
    echo "No argument supplied"
    exit 1
fi

a=0
b=1
while (( $b < $1 )); do
    echo "$b"
    olda=$a
    a=$b
    b=$(($olda + $b))
done

Este script demonstra também a utilização do comando if para verificar se foi dado o valor máximo para o cálculo.

Supondo que este ficheiro está guardado com o nome fibonacci.sh, correr o script é feito com o comando:

[pf@deti-cte ~]$ ./fibonacci.sh 90
./fibonacci.sh
1
1
2
3
5
8
13
21
34
55
89
[pf@deti-cte ~]$ ./fibonacci.sh
./fibonacci.sh
No argument supplied