Linux Professional Institute Learning Logo.
Ir para o conteúdo principal
  • Home
    • Todos os recursos
    • LPI Materiais Didáticos
    • Colabore Conosco
    • Publishing Partners
    • Seja um Publishing Partner
    • Quem Somos
    • FAQ
    • Colaboradores
    • Contato
  • LPI.org
3.3 Lição 2
Tópico 1: A comunidade Linux e a carreira Open Source
1.1 A evolução do Linux e sistemas operacionais populares
  • 1.1 Lição 1
1.2 Principais Aplicações Open Source
  • 1.2 Lição 1
1.3 Entendendo o Software Open Source e suas Licenças
  • 1.3 Lição 1
1.4 Habilidades ICT e trabalhando no Linux
  • 1.4 Lição 1
Tópico 2: Encontrando seu caminho em um Sistema Linux
2.1 O básico sobre a linha de comando
  • 2.1 Lição 1
  • 2.1 Lição 2
2.2 Usando a linha de comando para conseguir ajuda
  • 2.2 Lição 1
2.3 Usando diretórios e listando arquivos
  • 2.3 Lição 1
  • 2.3 Lição 2
2.4 Criando, Movendo e Deletando Arquivos
  • 2.4 Lição 1
Tópico 3: O Poder da Linha de Comando
3.1 Empacotando arquivos na linha de comando
  • 3.1 Lição 1
3.2 Pesquisando e extraindo dados de arquivos
  • 3.2 Lição 1
  • 3.2 Lição 2
3.3 Transformando comandos em Scripts
  • 3.3 Lição 1
  • 3.3 Lição 2
Tópico 4: O Sistema Operacional Linux
4.1 Escolhendo um Sistema Operacional
  • 4.1 Lição 1
4.2 Entendendo o Hardware do Computador
  • 4.2 Lição 1
4.3 Onde os dados são armazenados
  • 4.3 Lição 1
  • 4.3 Lição 2
4.4 Seu Computador na Rede
  • 4.4 Lição 1
Tópico 5: Segurança e Permissões de Arquivos
5.1 Segurança Básica e Identificação de Tipos de Usuários
  • 5.1 Lição 1
5.2 Criando Usuários e Grupos
  • 5.2 Lição 1
5.3 Gerenciando permissões e donos de arquivos
  • 5.3 Lição 1
5.4 Diretórios e arquivos especiais
  • 5.4 Lição 1
How to get certified
  1. Tópico 3: O Poder da Linha de Comando
  2. 3.3 Transformando comandos em Scripts
  3. 3.3 Lição 2

3.3 Lição 2

Certificação:

Linux Essentials

Versão:

1.6

Tópico:

3 O poder da linha de comando

Objetivo:

3.3 Como transformar comandos em script

Lição:

2 of 2

Introdução

Na última seção, usamos este exemplo simples para demonstrar a criação de scripts no Bash:

#!/bin/bash

# Um script simples para saudar um único usuário.

if [ $# -eq 1 ]
then
  username=$1

  echo "Hello $username!"
else
  echo "Please enter only one argument."
fi
echo "Number of arguments: $#."
  • Todos os scripts devem começar com um shebang, que define o caminho para o intérprete.

  • Todos os scripts devem incluir comentários para descrever seu uso.

  • Este script em particular trabalha com um argumento, que é passado para o script quando chamado.

  • Este script contém uma declaração if, que testa as condições de uma variável interna $#. Essa variável foi configurada para o número de argumentos.

  • Se o número de argumentos passados para o script for igual a 1, o valor do primeiro argumento é passado para uma nova variável chamada username e o script ecoa uma saudação ao usuário. Caso contrário, uma mensagem de erro é exibida.

  • Finalmente, o script ecoa o número de argumentos. Isso é útil para a depuração (debugging).

Este é um exemplo útil para começar a explicar alguns dos outros recursos dos scripts Bash.

Códigos de saída

Você deve ter notado que nosso script tem dois estados possíveis: ou ele imprime "Hello <usuário>!" ou uma mensagem de erro. Isso é bastante normal para muitos dos utilitários fundamentais. Veja o cat, que você já deve estar conhecendo bem.

Vamos comparar um uso bem-sucedido do cat com uma situação em que ele falha. Relembrando, o exemplo acima é um script chamado new_script.sh.

$ cat -n new_script.sh

     1	#!/bin/bash
     2
     3	# Um script simples para saudar um único usuário.
     4
     5	if [ $# -eq 1 ]
     6	then
     7	  username=$1
     8
     9	  echo "Hello $username!"
    10	else
    11	  echo "Please enter only one argument."
    12	fi
    13	echo "Number of arguments: $#."

Este comando é bem-sucedido; vemos que a flag -n também imprimiu os números de linha. Isso é muito útil na depuração de scripts, mas note eles não fazem parte do script.

Agora vamos verificar o valor de uma nova variável interna $?. Por enquanto, observe somente a saída:

$ echo $?
0

Agora, vamos considerar uma situação em que o cat não funcionará. Primeiro, veremos uma mensagem de erro e, em seguida, verificaremos o valor de $?.

$ cat -n dummyfile.sh
cat: dummyfile.sh: No such file or directory
$ echo $?
1

A explicação para esse comportamento é a seguinte: qualquer execução do utilitário cat retornará um código de saída. O código de saída informa se o comando foi bem-sucedido ou se ocorreu um erro. Um código de saída zero indica que o comando foi concluído com êxito. Isso vale para quase todos os comandos do Linux com os quais trabalhamos. Qualquer outro código de saída indica algum tipo de erro. O código de saída do último comando a ser executado será armazenado na variável $?.

Os códigos de saída geralmente não são vistos por usuários humanos, mas são muito úteis ao escrever scripts. Considere um script que serve para copiar arquivos para uma unidade de rede remota. A tarefa de cópia pode falhar de diversas maneiras: por exemplo, a máquina local talvez não esteja conectada à rede ou a unidade remota pode estar cheia. Graças ao código de saída do nosso utilitário de cópia, podemos alertar o usuário sobre esses problemas ao executar o script.

É sempre uma boa ideia implementar códigos de saída, e é o que faremos agora. Temos dois caminhos em nosso script, um sucesso e um fracasso. Vamos usar zero para indicar o sucesso e um para indicar o fracasso.

     1	#!/bin/bash
     2
     3	# Um script simples para saudar um único usuário.
     4
     5	if [ $# -eq 1 ]
     6	then
     7	  username=$1
     8
     9	  echo "Hello $username!"
    10	  exit 0
    11	else
    12	  echo "Please enter only one argument."
    13	  exit 1
    14	fi
    15	echo "Number of arguments: $#."
$ ./new_script.sh Carol
Hello Carol!
$ echo $?
0

Note que o comando echo na linha 15 foi totalmente ignorado. O uso de exit encerra o script imediatamente e, portanto, essa linha nunca é encontrada.

Como manipular múltiplos argumentos

Até agora, nosso script pode tratar apenas de um único nome de usuário por vez. Qualquer número de argumentos além de um causará um erro. Vamos explorar como é possível tornar esse script mais versátil.

O primeiro instinto de um usuário pode ser usar mais variáveis posicionais como $2, $3 e assim por diante. Infelizmente, não podemos prever o número de argumentos que um usuário pode querer usar. Para resolver esse problema, será útil introduzir mais variáveis internas.

Vamos modificar a lógica do nosso script. Se houver zero argumentos, aparecerá um erro, mas qualquer outro número de argumentos fará o script ser bem-sucedido. Este novo script será chamado friendly2.sh.

     1	#!/bin/bash
     2
     3	# um script simples para saudar os usuários
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  echo "Hello $@!"
    11	  exit 0
    12	fi
$ ./friendly2.sh Carol Dave Henry
Hello Carol Dave Henry!

Existem duas variáveis internas que contêm todos os argumentos passados para o script: $@ e $*. Na maioria das vezes, ambas se comportam da mesma forma. O Bash analisará (parse) os argumentos e separará cada argumento quando encontrar um espaço entre eles. De fato, o conteúdo de $@ é o seguinte:

0

1

2

Carol

Dave

Henry

Se você conhece outras linguagens de programação, vai reconhecer esse tipo de variável como um arranjo (array). Para criar arranjos no Bash, basta pôr um espaço entre elementos como a variável FILES no script arraytest abaixo:

FILES="/usr/sbin/accept /usr/sbin/pwck/ usr/sbin/chroot"

Ele contém uma lista de diversos itens. Por enquanto, ele não é muito útil, porque ainda não introduzimos nenhuma maneira de gerir esses itens individualmente.

Loops for

Vamos voltar ao exemplo arraytest, mostrado anteriormente. Se você se lembra, neste exemplo estamos especificando um arranjo chamado FILES. O que precisamos é de uma maneira de “desdobrar” esta variável e acessar cada valor individual, um após o outro. Para isso, usaremos uma estrutura chamada loop for, presente em todas as linguagens de programação. Existem duas variáveis às quais nos referiremos: uma é o intervalo e a outra é o valor individual em que estamos trabalhando no momento. Este é o script em sua totalidade:

#!/bin/bash

FILES="/usr/sbin/accept /usr/sbin/pwck/ usr/sbin/chroot"

for file in $FILES
do
  ls -lh $file
done
$ ./arraytest
lrwxrwxrwx 1 root root 10 Apr 24 11:02 /usr/sbin/accept -> cupsaccept
-rwxr-xr-x 1 root root 54K Mar 22 14:32 /usr/sbin/pwck
-rwxr-xr-x 1 root root 43K Jan 14 07:17 /usr/sbin/chroot

Se você consultar novamente o exemplo friendly2.sh acima, verá que estamos trabalhando com um intervalo de valores contidos dentro de uma única variável $@. Por uma questão de clareza, chamaremos a última variável de username. Nosso script fica assim:

     1	#!/bin/bash
     2
     3	# um script simples para saudar os usuários
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  for username in $@
    11	  do
    12	    echo "Hello $username!"
    13	  done
    14	  exit 0
    15	fi

Lembre-se de que a variável definida aqui pode ter qualquer nome, e que todas as linhas entre do…​ done serão executadas uma vez para cada elemento do arranjo. Vamos observar a saída de nosso script:

$ ./friendly2.sh Carol Dave Henry
Hello Carol!
Hello Dave!
Hello Henry!

Agora vamos supor que queremos fazer a saída parecer um pouco mais humana. Queremos que a saudação apareça em uma só linha.

     1	#!/bin/bash
     2
     3	# um script simples para saudar os usuários
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  echo -n "Hello $1"
    11	  shift
    12	  for username in $@
    13	  do
    14	    echo -n ", and $username"
    15	  done
    16	  echo "!"
    17	  exit 0
    18	fi

A notar:

  • Ao usar -n com echo , suprimimos a nova linha após a impressão. Isso significa que todos os ecos serão impressos na mesma linha, e a nova linha será impressa somente após o ! na linha 16.

  • O comando shift removerá o primeiro elemento do arranjo, de modo que:

0

1

2

Carol

Dave

Henry

Se torna:

0

1

Dave

Henry

Observemos a saída:

$ ./friendly2.sh Carol
Hello Carol!
$ ./friendly2.sh Carol Dave Henry
Hello Carol, and Dave, and Henry!

Verificando erros com expressões regulares

Podemos querer verificar todos os argumentos que o usuário está inserindo. Por exemplo, se quisermos garantir que todos os nomes passados para friendly2.sh contenham apenas letras e que quaisquer caracteres ou números especiais causem um erro. Para executar essa verificação de erro, usaremos grep.

Lembre-se de que podemos usar expressões regulares com grep.

$ echo Animal | grep "^[A-Za-z]*$"
Animal
$ echo $?
0
$ echo 4n1ml | grep "^[A-Za-z]*$"
$ echo $?
1

O ^ e o $ indicam, respectivamente, o início e o fim da linha. O [A-Za-z] indica um intervalo de letras, maiúsculas ou minúsculas. O * é um quantificador e modifica o intervalo de letras para que ele vá de zero a muitas letras. Em resumo, o grep será bem-sucedido se a entrada consistir somente de letras, mas se não for o caso ele falhará.

A próxima coisa a observar é que o grep está retornando códigos de saída com base nas correspondências que encontra. Uma correspondência positiva retorna 0 e uma negativa retorna 1. Podemos usar isso para testar os argumentos dentro de nosso script.

     1	#!/bin/bash
     2
     3	# um script simples para saudar os usuários
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  for username in $@
    11	  do
    12	    echo $username | grep "^[A-Za-z]*$" > /dev/null
    13	    if [ $? -eq 1 ]
    14	    then
    15	      echo "ERROR: Names must only contains letters."
    16	      exit 2
    17	    else
    18	      echo "Hello $username!"
    19	    fi
    20	  done
    21	  exit 0
    22	fi

Na linha 12, estamos redirecionando a saída padrão para /dev/null, que é uma maneira simples de suprimi-la. Não queremos ver nenhuma saída do comando grep, mas somente testar seu código de saída, o que acontece na linha 13. Observe também que estamos usando um código de saída 2 para indicar um argumento inválido. Geralmente, é recomendável usar códigos de saída distintos para indicar erros diferentes; assim, um usuário mais experiente pode usar esses códigos de saída para solucionar problemas.

$ ./friendly2.sh Carol Dave Henry
Hello Carol!
Hello Dave!
Hello Henry!
$ ./friendly2.sh 42 Carol Dave Henry
ERROR: Names must only contains letters.
$ echo $?
2

Exercícios guiados

  1. Leia o conteúdo de script1.sh, abaixo:

    #!/bin/bash
    
    if [ $# -lt 1 ]
    then
      echo "This script requires at least 1 argument."
      exit 1
    fi
    
    echo $1 | grep "^[A-Z]*$" > /dev/null
    if [ $? -ne 0 ]
    then
      echo "no cake for you!"
      exit 2
    fi
    
    echo "here's your cake!"
    exit 0

    Qual a saída destes comandos?

    • ./script1.sh

    • echo $?

    • ./script1.sh cake

    • echo $?

    • ./script1.sh CAKE

    • echo $?

  2. Leia o conteúdo do arquivo script2.sh:

    for filename in $1/*.txt
    do
       cp $filename $filename.bak
    done

    Descreva a finalidade deste script em seu entendimento.

Exercícios Exploratórios

  1. Crie um script capaz de receber qualquer número de argumentos do usuário e que imprima apenas os argumentos com números maiores que 10.

Resumo

Nesta lição, você aprendeu:

  • O que são códigos de saída, o que significam e como implementá-los

  • Como verificar o código de saída de um comando

  • O que são os loops for e como usá-los com arranjos

  • Como usar grep, expressões regulares e códigos de saída para verificar dados inseridos pelo usuário em scripts.

Comandos usados nos exercícios:

shift

Remove o primeiro elemento de um arranjo.

Variáveis Especiais:

$?

Contém o código de saída do último comando executado

$@, $*

Contém todos os argumentos passados para o script, como um arranjo.

Respostas aos Exercícios Guiados

  1. Leia o conteúdo de script1.sh, abaixo:

    #!/bin/bash
    
    if [ $# -lt 1 ]
    then
      echo "This script requires at least 1 argument."
      exit 1
    fi
    
    echo $1 | grep "^[A-Z]*$" > /dev/null
    if [ $? -ne 0 ]
    then
      echo "no cake for you!"
      exit 2
    fi
    
    echo "here's your cake!"
    exit 0

    Qual a saída destes comandos?

    • Comando: ./script1.sh

      Saída: This script requires at least 1 argument.

    • Comando: echo $?

      Saída: 1

    • Comando: ./script1.sh cake

      Saída: no cake for you!

    • Comando: echo $?

      Saída: 2

    • Comando: ./script1.sh CAKE

      Saída: here’s your cake!

    • Comando: echo $?

      Saída: 0

  2. Leia o conteúdo do arquivo script2.sh:

    for filename in $1/*.txt
    do
       cp $filename $filename.bak
    done

    Descreva a finalidade deste script em seu entendimento.

    Este script faz cópias de segurança de todos os arquivos que terminam com .txt em um subdiretório definido no primeiro argumento.

Respostas aos Exercícios Exploratórios

  1. Crie um script capaz de receber qualquer número de argumentos do usuário e que imprima apenas os argumentos com números maiores que 10.

    #!/bin/bash
    
    for i in $@
    do
      echo $i | grep "^[0-9]*$" > /dev/null
      if [ $? -eq 0 ]
      then
        if [ $i -gt 10 ]
        then
          echo -n "$i "
        fi
      fi
    done
    echo ""

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

Próxima Lição

4.1 Escolhendo um Sistema Operacional (4.1 Lição 1)

Ir para a próxima lição

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

A LPI é uma organização sem fins lucrativos.

© 2023 O Linux Professional Institute (LPI) é um organismo de apoio aos profissionais de Open Source e referência mundial em certificação. Com mais de 200.000 pessoas certificadas, somos o principal organismo de certificação independente para Linux e Open Source do mundo. O LPI certificou profissionais de mais de 180 países, oferece exames em diversos idiomas e tem centenas de parcerias de formação em todo o globo.

Nossa missão é proporcionar oportunidades econômicas e criativas para todos, tornando universalmente acessível a certificação de conhecimentos e competências em matéria de Open Source.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Entre em Contato
  • Política de Privacidade e Cookies

Encontrou um erro ou quer ajudar a aprimorar esta página? Escreva pra nós.

© 1999–2023 The Linux Professional Institute Inc. Todos os direitos reservados.