Fundamentos de scripts de shell

Transforme sequências de comandos que você digita repetidamente em scripts Bash. Comece cada script com uma linha shebang e torne-o executável. Armazene valores em variáveis, proteja-os com aspas e capture a saída de comandos. Use códigos de saída para informar sucesso e falha e teste arquivos, textos e números para escolher o que acontece em seguida. Repita tarefas com laços for, while e until e passe argumentos para que um script atenda a vários casos. Por fim, agende a execução automática dos scripts com cron ou temporizadores do systemd e verifique se cada execução foi bem-sucedida.

BásicoAula 4 de 7 do curso Curso de Fundamentos de Linux

O que você vai aprender

  1. Transformar uma sequência de comandos que você digita repetidamente em um arquivo de script, iniciá-lo com a linha correta do interpretador e executá-lo a partir de qualquer diretório.
    • Transformar comandos repetidos em um arquivo de script
      Escrever comandos em ordem em um arquivo de texto simples, adicionar comentários e iniciar o arquivo com uma linha shebang que indique o Bash como interpretador.
    • Executar um script e escolher onde armazená-lo
      Tornar um script executável, executá-lo pelo caminho ou por meio de um interpretador, colocá-lo em um diretório no PATH e saber quando um script pode alterar seu shell atual.
  2. Guardar textos, números e saídas de comandos em variáveis, ler entradas do usuário e usar aspas para que espaços e caracteres especiais cheguem aos comandos sem alterações.
    • Criar, ler e exportar variáveis
      Atribuir e usar variáveis do shell, escolher bons nomes, ler entradas do usuário e passar variáveis aos programas iniciados por um script.
    • Proteger palavras, variáveis e caracteres especiais com aspas ou escape
      Escolher entre aspas simples, aspas duplas e barras invertidas e proteger cada expansão de variável com aspas para que espaços e caracteres curinga nos valores não prejudiquem um comando.
    • Capturar a saída de comandos e calcular com números inteiros
      Armazenar a saída de um comando com substituição de comando e fazer operações com números inteiros, por exemplo para criar nomes de arquivo com datas e manter contadores.
  3. Ler e definir o código de saída de comandos e scripts, encadear comandos conforme o sucesso ou a falha e encontrar e interromper erros antes que causem danos.
    • Ler e definir códigos de saída e usá-los para encadear comandos
      Usar o código de saída retornado por cada comando, encerrar um script com um código significativo e executar comandos apenas quando um comando anterior tiver sido bem-sucedido ou falhado.
    • Encontrar erros e encerrar um script com segurança
      Verificar e rastrear um script para encontrar erros, enviar mensagens de erro para a saída de erro padrão e fazer um script parar em caso de falhas, variáveis não definidas e falhas em encadeamentos.
  4. Testar arquivos, textos e números, escolher o que fazer com if e case e repetir comandos para itens de listas, arquivos e linhas com laços for, while e until.
    • Testar arquivos, strings e números
      Escrever condições com test, [ ] e [[ ]] para verificar se arquivos existem, comparar textos e números inteiros e combinar ou negar essas condições.
    • Escolher ações com if, elif, else e case
      Executar comandos diferentes conforme uma condição com if, elif e else e comparar um valor com vários padrões usando case.
    • Repetir comandos para itens de listas e arquivos com for
      Percorrer uma lista de palavras, os arquivos que correspondem a um padrão, um intervalo de números ou os argumentos de um script e lidar com nomes de arquivo que contêm espaços.
    • Repetir comandos até que uma condição mude com while e until
      Executar comandos enquanto uma condição for bem-sucedida ou até que ela seja, ler um arquivo linha por linha e controlar laços com break, continue e sleep.
  5. Fornecer entradas a um script na linha de comando, ler os argumentos dentro do script, verificá-los e fornecer valores padrão para que o mesmo script funcione em vários casos.
    • Ler parâmetros posicionais e a quantidade de argumentos
      Usar $0, $1 a $9, ${10}, $# e "$@" para ler as palavras fornecidas após o nome de um script e usar shift para percorrê-las.
    • Verificar argumentos, mostrar instruções de uso e definir valores padrão
      Validar a quantidade e o tipo dos argumentos, imprimir uma mensagem de uso e sair com um código de erro, usar valores padrão e tratar opções simples.
  6. Executar scripts em horários ou intervalos definidos sem estar conectado, com cron ou temporizadores do systemd, e verificar se as execuções agendadas ocorrem e são bem-sucedidas.
    • Agendar tarefas com cron
      Escrever entradas de crontab com os cinco campos de tempo, editá-las e listá-las com crontab e preparar scripts para o ambiente mínimo do cron.
    • Agendar tarefas com temporizadores do systemd
      Associar uma unidade de serviço a uma unidade de temporizador, escrever agendamentos por calendário e por intervalo, habilitar o temporizador e verificar a próxima execução e os logs.

Guia de estudo de Scripts de shell

6 capítulos

1

Escrever e executar seus primeiros scripts Bash

Alguns comandos ficam mais fáceis de repetir quando estão em um único script. Você indicará um interpretador Bash para o arquivo, manterá suas instruções legíveis e escolherá como iniciá-lo. As permissões de arquivo, os caminhos de busca de comandos e os shells filhos explicam algumas situações comuns: por que um script funciona com bash, mas falha com ./, por que seu nome não é encontrado e por que suas mudanças de diretório não movem seu terminal.

1.1 Transformar comandos repetidos em um arquivo de script

Um script de shell salva uma sequência de comandos em um arquivo de texto simples. O Bash lê os comandos em ordem, assim como lê os comandos que você digita em um prompt. Um script pode repetir uma tarefa sem que alguém digite cada etapa e oferece um único lugar para corrigir ou melhorar essa tarefa.

Coloque o interpretador na primeira linha

O shebang informa ao Linux qual programa deve ler um script executável. Comece um script Bash com #!/bin/bash. #! deve ser os dois primeiros caracteres do arquivo: sem espaços ou linha em branco antes deles. Bash significa Bourne Again Shell. Ele é amplamente usado como shell interativo no Linux e também lê arquivos de script.

Um interpretador é um programa que lê e executa outra linguagem. O mesmo mecanismo permite que #!/usr/bin/python3 selecione o Python ou que #!/usr/bin/awk -f selecione o awk. O restante de um script Bash deve conter comandos de shell que o Bash entenda.

Crie backup-notes.sh em um editor de texto simples, como nano ou vi:

#!/bin/bash
# Keep a copy of the notes and show the backup folder.
mkdir -p ~/backup
cp ~/notes.txt ~/backup/
ls -l ~/backup

O Bash primeiro cria o diretório de destino, depois copia as anotações e, em seguida, lista o destino. mkdir -p também é bem-sucedido quando o diretório já existe, portanto uma execução posterior pode reutilizá-lo. O arquivo de origem ~/notes.txt deve existir para que a cópia funcione. Salvar os comandos não cria esse arquivo de origem.

Torne o arquivo legível para as pessoas

A segunda linha é um comentário. Fora de texto entre aspas, # inicia um comentário no começo de uma palavra; o Bash ignora o restante dessa linha. Escreva comentários sobre a finalidade de uma etapa, como o motivo para manter uma cópia de segurança. Linhas em branco e indentação facilitam a identificação de grupos de comandos. Mantenha a indentação consistente ao adicionar condições e laços.

A terminação .sh ajuda o leitor a reconhecer um script de shell. O Linux não exige essa terminação, e adicioná-la não seleciona o Bash nem concede permissão de execução. Um arquivo chamado backup-notes pode executar os mesmos comandos.

Escolha o shell adequado à linguagem
Primeira linhaComo o interpretador é escolhido
#!/bin/bashUsa o Bash no caminho fixo /bin/bash.
#!/usr/bin/env bashUsa env para encontrar o Bash por meio do PATH.
#!/bin/shUsa o sh do sistema, que pode ser outro shell.

No Debian e no Ubuntu, /bin/sh normalmente seleciona o dash. Recursos do Bash, como [[ ... ]], falham nele. Um script Bash precisa de um interpretador Bash, mesmo que comandos simples funcionem em ambos os shells. Chamar um arquivo de something.sh não corrige um shebang incompatível.

Reconheça um problema de terminador de linha

Editores do Windows podem salvar um retorno de carro antes de cada caractere de nova linha. No Linux, esse caractere invisível pode se tornar parte do caminho no shebang. Um erro como /bin/bash^M: bad interpreter: No such file or directory aponta para esse problema, mesmo que /bin/bash exista.

Converta o arquivo para terminadores de linha do Unix com dos2unix backup-notes.sh e, depois, salve os próximos scripts com terminadores de linha do Unix no editor. Os comandos do arquivo podem estar corretos enquanto o caractere extra impede o Linux de iniciar seu interpretador.

Principais conclusões

  • Um script é um texto simples que contém comandos a serem executados em ordem.
  • O shebang deve começar no início do arquivo e indicar o interpretador correto.
  • Use comentários e indentação para deixar claras a finalidade e a estrutura.
  • A extensão .sh é uma convenção; ela não seleciona um shell.
  • Terminadores de linha do Unix impedem que um retorno de carro oculto prejudique o shebang.

1.2 Executar um script e escolher onde armazená-lo

Um script pode ser lido diretamente pelo Bash ou iniciado como um programa. Essas formas diferem nas permissões necessárias e em como o interpretador é escolhido. O caminho digitado também determina se o shell busca um comando ou usa um arquivo específico.

Duas maneiras de iniciar o mesmo arquivo
bash backup-notes.sh
chmod u+x backup-notes.sh
./backup-notes.sh

O primeiro comando inicia o Bash e pede que ele leia o arquivo. O script precisa de permissão de leitura; seu próprio bit de execução não é necessário. O Bash trata o shebang como comentário porque o interpretador já foi escolhido.

O segundo comando adiciona permissão de execução para o proprietário do arquivo. Em uma sequência de permissões como -rwxr--r--, o x do proprietário significa que o arquivo é executável. O terceiro comando executa o arquivo como um programa e usa seu shebang. chmod +x também é comum; sem uma classe de permissões indicada, a umask limita quais classes recebem permissão de execução. chmod u+x direciona a alteração explicitamente ao proprietário.

Se ./backup-notes.sh informar “Permission denied”, verifique a permissão de execução e o acesso ao caminho. Se bash backup-notes.sh funcionar, isso não comprova que a execução direta tenha as permissões necessárias.

Entenda a busca de comandos

./ significa o diretório atual. Quando um comando contém uma barra, o Bash segue esse caminho. Quando você digita um nome sem barra, o Bash busca nos diretórios do PATH. O diretório atual normalmente está ausente dessa lista, portanto estar dentro do diretório de um script não basta para executá-lo apenas pelo nome.

echo "$PATH"
command -v backup-notes.sh
type backup-notes.sh

PATH é uma lista separada por dois-pontos, como /home/sam/.local/bin:/usr/local/bin:/usr/bin:/bin. O primeiro executável correspondente prevalece. Os dois últimos comandos ajudam a identificar o que será executado para um nome, incluindo uma cópia mais antiga em outro lugar do PATH.

Para disponibilizar um script pessoal pelo nome, coloque-o em um diretório do seu PATH. Muitas distribuições adicionam ~/bin ou ~/.local/bin no login quando esse diretório existe; confira seu PATH. /usr/local/bin é um local comum para scripts compartilhados entre usuários e exige direitos de administrador para gravação.

Escolha um shell filho ou o shell atual

Executar ./settings.sh ou bash settings.sh inicia um processo Bash filho. Suas variáveis e mudanças de diretório pertencem a esse processo filho. Um script que contém cd /var/log não muda o diretório do terminal que o iniciou. Quando ele termina, você ainda está no diretório original do terminal.

A execução no shell atual (sourcing) lê comandos no shell atual:

source ./settings.sh
# Equivalent short form:
. ./settings.sh

Use essa forma para um arquivo de configuração destinado a alterar sua sessão. Ela exige permissão de leitura, não de execução, e um shebang não inicia um interpretador separado. Portanto, executar um arquivo de configuração Bash no shell atual pressupõe que esse shell entenda a sintaxe do Bash.

Leia o resultado de uma execução

Imediatamente após o término de um script, echo $? mostra seu código de saída. A menos que o script use exit com um código escolhido, seu código vem do último comando. Assim, uma listagem final bem-sucedida pode ocultar uma falha anterior na cópia; as verificações de erro apresentadas mais adiante permitirão que o script informe o resultado real da tarefa.

Principais conclusões

  • bash file lê um script com o Bash; ./file exige permissão de execução e usa o shebang.
  • O PATH é consultado apenas para nomes de comando sem barra.
  • Verifique um nome de comando com command -v ou type.
  • A execução inicia um shell filho; a execução no shell atual pode alterá-lo.
2

Armazenar valores em variáveis e protegê-los com aspas com segurança

Variáveis permitem que os mesmos comandos funcionem com caminhos, nomes e contagens que mudam. As aspas mantêm esses valores intactos enquanto o Bash monta uma linha de comando, de modo que um espaço em um nome continue fazendo parte dele. Você lerá entradas, passará valores a programas filhos, capturará a saída de comandos e calculará com números inteiros. Esses recursos funcionam juntos quando um script cria um nome de arquivo com data ou mantém uma contagem acumulada.

2.1 Criar, ler e exportar variáveis

Uma variável dá um nome a um valor para que o mesmo script possa reutilizá-lo. Variáveis do Bash normalmente armazenam texto, mesmo quando esse texto parece um número. Você atribui o valor uma vez e expande o nome sempre que um comando precisar dele.

Faça atribuições sem espaços
city=Lisbon
greeting="Good morning"
echo "$greeting from $city"

A saída é “Good morning from Lisbon.” Não há espaços ao redor do = de atribuição. Em city = Lisbon, o Bash trata city como comando e as outras palavras como argumentos. As aspas ao redor de "Good morning" mantêm as duas palavras em um único valor.

Use letras, dígitos e sublinhados nos nomes de variáveis, começando com uma letra ou um sublinhado. Os nomes diferenciam maiúsculas de minúsculas: file, File e FILE são diferentes. Escolha nomes em minúsculas, como backup_dir, para valores pertencentes ao seu script. Isso ajuda a evitar a substituição de variáveis de ambiente como PATH ou HOME. Definir PATH=/data altera a localização de comandos e pode fazer com que comandos comuns deixem de ser encontrados.

Marque onde um nome termina

Um cifrão introduz uma expansão. As chaves mostram o limite quando há mais texto imediatamente em seguida:

file=report
echo "${file}_old"

Isso imprime “report_old.” Com "$file_old", o Bash procura uma variável chamada file_old, não file seguida de _old. Sem set -u, um nome não definido é expandido para texto vazio. Assim, um erro de digitação pode produzir um caminho ou uma mensagem vazia sem erro imediato.

Um valor como count=5 armazena o texto “5.” Adicionar texto ao lado de uma expansão não faz um cálculo: echo "$count+1" imprime “5+1.” A expansão aritmética dá aos números um papel diferente quando cálculos são necessários.

Leia uma linha de entrada
read -r -p "Your name: " name
echo "Hello, $name"

read armazena a linha digitada em name. -p fornece o prompt e -r preserva as barras invertidas. Com a entrada “Lee Kim”, a saudação é “Hello, Lee Kim.” Um script executado sem uma pessoa presente precisa receber suas entradas de argumentos, arquivos ou valores padrão; um prompt não pode fornecer um valor ausente de maneira confiável.

Exporte valores para programas filhos

Uma variável comum do shell pertence ao shell no qual é definida. A exportação marca a variável para inclusão no ambiente copiado aos programas que esse shell inicia:

export BACKUP_DIR=/mnt/usb
bash backup-notes.sh

O Bash filho agora pode ler BACKUP_DIR. Se esse processo filho atribuir outro valor, o processo pai mantém seu próprio valor. A herança do ambiente passa do processo pai para o filho; ela não envia alterações posteriores de volta.

NomeSignificado usual
HOMEDiretório pessoal
USERNome de usuário
PWDDiretório de trabalho atual
PATHDiretórios pesquisados para nomes de comandos

env ou printenv exibe variáveis de ambiente. unset name remove a variável chamada name; ele não atribui uma string vazia. Na expansão normal, ambos podem parecer vazios, mas uma verificação de variável não definida pode distinguir uma variável ausente de uma definida.

Principais conclusões

  • Atribuições usam name=value sem espaços ao redor de =.
  • Nomes de variáveis diferenciam maiúsculas de minúsculas; use nomes em minúsculas para seus próprios valores.
  • ${name} marca o fim de um nome de variável antes de texto adjacente.
  • read -r lê a entrada preservando as barras invertidas.
  • Valores exportados são copiados para processos filhos, nunca de volta para um processo pai.
  • unset remove uma variável.

2.2 Proteger palavras, variáveis e caracteres especiais com aspas ou escape

O Bash lê um comando antes de o programa receber seus argumentos. Espaços separam palavras, e caracteres como *, ?, $, ;, &, |, < e > têm funções especiais. A proteção com aspas ou escape controla quais dessas funções permanecem ativas.

Escolha o que deve ser expandido
FormaO que o Bash faz
'fixed text'Mantém tudo dentro das aspas como literal.
"text with $name"Preserva espaços e caracteres curinga, mas expande variáveis, saída de comandos e expressões aritméticas.
\*Trata o próximo caractere literalmente fora de aspas.

Com HOME=/home/sam, compare:

echo 'Home: $HOME *'
echo "Home: \$HOME *"

O primeiro imprime “Home: $HOME *”. O segundo imprime “Home: /home/sam *”. O asterisco permanece literal em ambos, mas apenas as aspas duplas permitem que a variável seja expandida. Uma aspa simples não pode ser colocada diretamente dentro de uma string entre aspas simples.

Dentro de aspas duplas, barras invertidas podem proteger um cifrão, uma crase, uma aspa dupla ou uma barra invertida. Por exemplo, echo "Price: \$5" imprime “Price: $5”. Fora de aspas, echo 5 \* 3 imprime “5 * 3”, e touch my\ file.txt cria um arquivo com um espaço no nome.

Acompanhe um valor sem aspas pelo Bash
file="my report.txt"
cp $file backup/

Primeiro, o Bash expande a variável. Depois, a separação de palavras divide seu valor em espaços, tabulações e caracteres de nova linha. O comando recebe my, report.txt e backup/ como argumentos separados. Ele tenta copiar dois arquivos de origem em vez do único arquivo pretendido.

Se uma palavra resultante contiver caracteres curinga, a expansão de nomes de arquivo a substitui pelos nomes correspondentes. Um valor armazenado de *.txt pode se tornar vários argumentos de arquivo quando expandido sem aspas. Essas etapas adicionais ocorrem antes de cp iniciar; o programa não consegue recuperar o agrupamento pretendido.

cp "$file" backup/

Agora o valor expandido permanece como um argumento, “my report.txt”. Os próprios caracteres de aspas são removidos pelo Bash; eles são instruções de interpretação, não parte do caminho passado a cp. Coloque aspas duplas ao redor de expansões de variáveis e substituições de comando sempre que seu valor completo deva permanecer junto.

Mantenha presente um valor vazio

As aspas também importam quando um valor está vazio. Em [ $answer = yes ], um answer vazio desaparece, deixando um teste inválido. [ "$answer" = yes ] passa uma string vazia como um argumento, portanto o teste é válido e falso.

A mesma regra de agrupamento se aplica a palavras literais. mkdir new folder cria dois diretórios, enquanto mkdir "new folder" cria um. Colocar um caminho inteiro entre aspas é útil tanto quando seu espaço foi digitado diretamente quanto quando veio de uma variável.

Combine texto literal e expandido

Partes adjacentes entre aspas, sem espaço entre elas, formam uma palavra. Com price=8, echo 'Price: $'"$price" imprime “Price: $8”. A parte fixa está entre aspas simples e a parte variável está entre aspas duplas. Um padrão de busca também pode ser mantido fixo: grep 'cost: \$[0-9]' prices.txt passa seu padrão sem expansão pelo shell, deixando que grep o interprete.

Principais conclusões

  • Aspas simples mantêm o texto literal; aspas duplas permitem expansões e mantêm os valores juntos.
  • Expansões sem aspas passam pela separação de palavras e depois pela expansão de nomes de arquivo.
  • Aspas preservam um valor vazio como argumento.
  • Uma barra invertida pode tornar literal um caractere especial.
  • Partes adjacentes entre aspas formam uma palavra quando não há espaço entre elas.

2.3 Capturar a saída de comandos e calcular com números inteiros

Comandos muitas vezes produzem um valor necessário em outra etapa. O Bash pode capturar essa saída, colocá-la dentro de um texto ou usá-la em um cálculo. A substituição de comando e a expansão aritmética têm pontuação semelhante, mas cumprem funções diferentes.

Capture a saída padrão
today=$(date +%F)
cp notes.txt "notes-${today}.txt"

$(...) executa um comando e substitui a expressão por sua saída padrão. Em 2026-10-22, today contém “2026-10-22” e a cópia recebe o nome notes-2026-10-22.txt. Uma data na ordem ano-mês-dia mantém os nomes de arquivo em ordem de data quando são ordenados pelo nome. Você também pode colocar a substituição diretamente no nome: "notes-$(date +%F).txt".

Os caracteres de nova linha no final são removidos da saída capturada. A forma mais antiga com crases também captura a saída, mas $(...) é mais fácil de ler e aninhar. Coloque entre aspas uma substituição usada como argumento de comando, como "$(date +%F)", para manter seu resultado junto.

A substituição de comando captura apenas a saída padrão. Erros enviados à saída de erro padrão ainda vão para seu destino habitual. result=$(some_command 2>&1) combina ambos os fluxos dentro da captura quando isso é o que o script precisa. Misturar erros a um valor destinado a conter um número faria a aritmética posterior falhar.

Capture uma contagem sem o nome do arquivo
lines=$(wc -l < access.log)
echo "Lines: $lines"

Se o arquivo contiver 342 caracteres de nova linha, wc fornece a contagem 342. Redirecionar o arquivo para wc faz sua saída conter apenas a contagem; wc -l access.log também imprime o nome do arquivo. Um resultado com aparência numérica pode então ser reutilizado, desde que o comando tenha sido bem-sucedido.

Calcule com números inteiros

$(( ... )) realiza a expansão aritmética:

echo "$(( 17 / 5 ))"
echo "$(( 17 % 5 ))"

Os resultados são 3 e 2. A divisão inteira descarta o resto; % o retorna. Adição, subtração e multiplicação usam +, - e *. Nomes de variáveis podem aparecer sem cifrão dentro da expressão: total=$(( price * qty )).

Com a=5, echo "$a+3" imprime “5+3” como texto. echo "$(( a + 3 ))" calcula e imprime 8. Os parênteses adicionais selecionam a aritmética; $(a + 3) tentaria executar um comando chamado a.

Um contador começa com um valor como count=0 e é atualizado com count=$(( count + 1 )). O Bash também oferece (( count++ )); esse é um comando aritmético com seu próprio código de saída, o que importa em scripts que usam opções de erro.

Mantenha a precisão necessária

A aritmética do Bash usa números inteiros. 7 / 2 resulta em 3, e um valor decimal como 2.5 causa um erro de sintaxe aritmética. Uma ferramenta separada pode calcular com decimais:

echo "scale=2; 7 / 2" | bc

Isso produz 3.50. Na aritmética inteira, multiplique antes de dividir quando o produto preservar uma fração de que você ainda precisa. Para 45 de 60, $(( 45 * 100 / 60 )) resulta em 75. Dividir primeiro resulta em zero para 45 / 60, portanto $(( 45 / 60 * 100 )) permanece zero; a fração perdida não pode ser recuperada pela multiplicação posterior.

Principais conclusões

  • $(command) captura a saída padrão e remove os caracteres de nova linha no final.
  • $((expression)) calcula com números inteiros.
  • Use / para divisão inteira e % para seu resto.
  • Um contador armazena seu valor atualizado após cada incremento.
  • Multiplicar antes de dividir pode evitar a perda prematura de precisão na aritmética inteira.
  • Use uma ferramenta como bc quando for necessário um resultado decimal.
3

Informar sucesso e falha com códigos de saída

Um script precisa de um resultado que tanto pessoas quanto programas possam entender. A saída impressa explica o que aconteceu, enquanto um código de saída permite que outro comando decida se deve continuar. Você salvará esse código, verificará etapas dependentes e manterá visíveis as falhas em encadeamentos. Verificações de sintaxe, rastreamentos de execução e opções de erro ajudam a encontrar a causa de uma falha antes que comandos posteriores tornem seus efeitos mais difíceis de identificar.

3.1 Ler e definir códigos de saída e usá-los para encadear comandos

Um comando informa seu resultado de duas maneiras: ele pode imprimir texto e retorna um código de saída. Programas usam esse código para decidir o que acontece em seguida. Um script pode imprimir uma mensagem tranquilizadora e ainda assim ter falhado, ou não imprimir nada e ser bem-sucedido.

Leia um código antes que ele mude

Um código de saída é um número inteiro de 0 a 255. Zero significa sucesso. Um valor diferente de zero informa uma falha ou outro resultado documentado. grep, por exemplo, usa 0 para uma correspondência, 1 para nenhuma correspondência e 2 para um erro. Uma busca sem correspondência pode ser um resultado normal para sua tarefa, embora seu código seja diferente de zero.

$? armazena o código do comando mais recente:

grep -q root /etc/passwd
status=$?
echo "Search status: $status"

A atribuição salva o resultado antes que outro comando o substitua. Em ls /missing; echo $?; echo $?, o ls do GNU retorna 2 para o caminho inacessível fornecido na linha de comando. O primeiro echo imprime 2 e depois é bem-sucedido. O segundo imprime 0, o código desse echo, não da listagem original.

Termine com um resultado útil

exit 1 encerra um script imediatamente e informa 1 a quem o chamou. exit 0 informa sucesso. Um exit sem número usa o código do comando anterior; chegar ao fim normalmente usa o código do último comando. Escolha códigos entre 0 e 255: exit 256 dá a volta para 0 e informaria sucesso incorretamente.

Alguns códigos vêm do próprio Bash:

CódigoSignificado
127O comando não foi encontrado.
126O comando foi encontrado, mas não pôde ser executado.
128 + nO comando terminou por causa do sinal de número n.

Ctrl+C envia o sinal 2, portanto um comando encerrado dessa forma costuma informar 130. Programas comuns também documentam seus próprios códigos; 1 e 2 não têm um significado universal para todas as ferramentas.

Encadeie comandos dependentes
mkdir -p ~/backup && cp notes.txt ~/backup/
cd /data/reports || exit 1

&& executa o próximo comando apenas após um sucesso. Aqui, a cópia depende da criação ou localização do diretório de cópia de segurança. || executa o próximo comando apenas após uma falha. Aqui, uma mudança de diretório malsucedida interrompe o script antes que comandos posteriores usem o diretório de trabalho errado.

true retorna 0; false retorna 1. Um ! no início inverte o sucesso ou a falha de um comando. ! grep -q ERROR app.log é bem-sucedido quando a busca não encontra uma linha correspondente, embora também seja bem-sucedido se grep falhar com um erro; use verificações explícitas do código de saída quando for necessário distinguir esses resultados.

Verifique um encadeamento inteiro
grep ERROR missing.log | wc -l

Por padrão, um encadeamento tem o código de saída de seu comando final. grep falha devido ao arquivo ausente, mas wc lê um fluxo vazio, imprime 0 e é bem-sucedido. Portanto, o código do encadeamento é 0.

set -o pipefail faz um encadeamento falhar quando qualquer um de seus comandos falha. Ele informa o código diferente de zero mais à direita, ou 0 se todos os comandos forem bem-sucedidos. Isso torna os erros anteriores no encadeamento visíveis para if, &&, || e quem chamou o script. Um agendador pode então distinguir um relatório bem-sucedido de um que nunca leu sua entrada.

Principais conclusões

  • O código de saída 0 significa sucesso; resultados diferentes de zero têm significados documentados por cada programa.
  • Salve $? imediatamente se precisar usá-lo após outro comando.
  • exit fornece um resultado a quem chamou o script.
  • && continua após o sucesso, e || continua após a falha.
  • Sem pipefail, um encadeamento informa apenas o código de saída de seu último comando.

3.2 Encontrar erros e encerrar um script com segurança

O Bash normalmente continua após a falha de um comando. Se o próximo comando depender desse trabalho, continuar pode transformar uma pequena falha em um problema maior. Verifique explicitamente as etapas dependentes e use a verificação de sintaxe e o rastreamento para descobrir por que uma execução se comporta de forma diferente do planejado.

Interrompa a execução antes que uma falha se propague
cd /backups || exit 1

Agora, os comandos seguintes só podem ser executados após uma mudança de diretório bem-sucedida. Isso importa antes de operações com arquivos: se uma mudança de diretório falhar e o script continuar, os caminhos relativos ainda se referirão ao diretório antigo. Verifique o destino antes de executar comandos que alteram ou excluem arquivos.

Uma mensagem de erro e um código de falha atendem a leitores diferentes:

echo "Error: $file not found" >&2
exit 1

A mensagem vai para a saída de erro padrão, deixando a saída padrão disponível para dados. Com ./report.sh > report.txt, a mensagem permanece visível no terminal enquanto a saída normal entra no arquivo. O código diferente de zero permite que outro programa detecte o erro sem ler a frase.

Verifique a sintaxe e depois rastreie a execução
ComandoO que faz
bash -n script.shLê a sintaxe sem executar comandos.
bash -x script.shExecuta o script e imprime os comandos expandidos antes de executá-los.

A falta de fi, done ou de uma aspa de fechamento é um problema de sintaxe. bash -n pode localizá-lo, muitas vezes por meio de uma mensagem “unexpected end of file”. Um caminho de arquivo com sintaxe válida, mas digitado incorretamente, precisa de uma verificação durante a execução.

O rastreamento precede os comandos com +. Uma linha como cp "$src" "$dest" revela os caminhos reais recebidos. set -x e set +x ativam e desativam o rastreamento em torno de uma seção.

Entenda as opções de erro

set -euo pipefail combina três controles:

  • -e encerra a execução após uma falha de comando não tratada.
  • -u informa uma variável não definida como erro.
  • pipefail faz com que falhas de comandos afetem o código de saída do encadeamento.

-e permite falhas esperadas em condições if, while e until, comandos negados e comandos que não são os últimos em listas && ou ||. Sem pipefail, uma falha antes do comando final de um encadeamento não provoca a saída. Verificações explícitas continuam úteis porque indicam o que o script deve fazer quando uma etapa específica falha.

Um comando aritmético também informa verdadeiro ou falso. (( count++ )) retorna o código 1 quando o valor antigo é 0, portanto um uso não tratado sob -e pode interromper o script mesmo que o incremento tenha ocorrido. A atribuição count=$(( count + 1 )) evita esse código de saída do comando aritmético.

-u detecta um erro de digitação como $filname quando apenas filename foi definida. Ele não rejeita uma variável que existe, mas está vazia. ${dir:?not set} verifica se dir está ausente ou vazia nessa expansão. Um resultado esperado sem correspondência pode ser tratado com um teste; command || true suprime todas as falhas desse comando, portanto use-o apenas quando todas elas forem aceitáveis.

Leia as mensagens e faça a limpeza

“Command not found” aponta para um problema no nome, no programa instalado ou no PATH. “Permission denied” aponta para execução ou acesso a arquivo. “Unary operator expected” normalmente decorre de um valor vazio sem aspas em [ ]; “integer expression expected” significa que um teste numérico recebeu texto.

Um trap em EXIT define uma ação de limpeza, como trap 'rm -f "$tmpfile"' EXIT, depois que tmpfile recebe um valor. O comando entre aspas é executado quando o Bash sai, inclusive após um exit explícito ou uma saída por erro sob -e. O ShellCheck também pode inspecionar scripts antes da execução em busca de erros comuns de proteção com aspas e de lógica.

Principais conclusões

  • Verifique uma etapa antes de executar comandos que dependem dela.
  • Escreva mensagens de diagnóstico na saída de erro padrão e informe falhas com um código diferente de zero.
  • bash -n verifica a sintaxe; bash -x executa e rastreia.
  • set -e tem exceções para falhas que estão sendo testadas.
  • set -u detecta variáveis não definidas, enquanto ${name:?message} também rejeita valores vazios.
  • Um trap em EXIT pode remover um arquivo temporário quando o script termina.
4

Tomar decisões e repetir tarefas

Um script útil escolhe ações e as repete para entradas que mudam. Testes transformam perguntas sobre arquivos, textos e números em sucesso ou falha. Ramos selecionam uma ação, enquanto laços aplicam comandos a listas ou continuam até que uma condição mude. Você acompanhará o valor usado em cada passagem e preservará espaços, registros e contadores enquanto os dados percorrem o script.

4.1 Testar arquivos, strings e números

Uma condição no Bash é um comando cujo código de saída significa verdadeiro ou falso. Testes permitem fazer perguntas sobre caminhos, textos e números. Escolha um operador adequado ao tipo de valor; os mesmos caracteres impressos podem ter significados diferentes como texto e como número.

Separe os elementos do teste

test -f notes.txt e [ -f notes.txt ] verificam se um caminho se refere a um arquivo comum existente. [ é um comando, e seu último argumento deve ser ]. Espaços separam seus argumentos:

[ -f "$file" ]

Sem o espaço após [, o Bash pode procurar um comando chamado [-f. Em [ "$a"="$b" ], a falta de espaços ao redor de = forma uma palavra não vazia, cujo teste é verdadeiro mesmo que os valores sejam diferentes. Operadores devem ser argumentos separados.

Escolha um teste de arquivo
OperadorVerdadeiro quando o caminho…
-eExiste.
-fÉ um arquivo comum existente.
-dÉ um diretório existente.
-r, -w, -xPode ser lido, gravado ou executado pelo usuário atual.
-sExiste e tem tamanho maior que zero.
-LÉ um link simbólico.

Para um diretório chamado logs, -e e -d são bem-sucedidos, enquanto -f falha. Testes de arquivo normalmente seguem um link simbólico até seu destino; -L verifica o próprio link. Portanto, um link quebrado pode satisfazer -L e falhar em -e.

Compare textos ou números inteiros

Testes de strings usam = e != para igualdade e desigualdade. -z verifica se o comprimento é zero e -n se o comprimento é diferente de zero. [ "$answer" = yes ] corresponde exatamente a “yes”; “Yes” e “yes ” são textos diferentes. Aspas duplas mantêm um valor vazio no teste.

Comparações de números inteiros usam -eq, -ne, -lt, -le, -gt e -ge: igual, diferente, menor que, menor ou igual, maior que e maior ou igual. [ "$count" -gt 100 ] verifica se o número é maior que 100.

[ 07 -eq 7 ]
[ 07 = 7 ]

A comparação numérica é bem-sucedida porque os valores são iguais. A comparação de strings falha porque um dos textos começa com um zero a mais.

Não use > isolado para um teste numérico dentro de [ ]. Em [ 10 > 9 ], o Bash redireciona a saída para um arquivo chamado 9 e testa a palavra não vazia restante. Em [[ 10 < 9 ]] no Bash, o operador compara strings, portanto o caractere inicial 1 vem antes de 9. Use -lt ou -gt para comparações numéricas, ou aritmética do Bash, como (( count > 100 )).

Combine condições

[ ! -d "$dir" ] é bem-sucedido quando o caminho não é um diretório existente; ele pode ser um arquivo comum ou estar ausente. [ -f "$f" ] && [ -r "$f" ] é bem-sucedido apenas quando ambos os testes são bem-sucedidos. Testes separados unidos por || são bem-sucedidos quando pelo menos um é bem-sucedido.

O Bash também tem a palavra-chave condicional [[ ... ]]. Ela impede a separação em palavras das expansões de variáveis e permite && e || em seu interior. Um padrão sem aspas à direita de == faz uma correspondência de padrões: [[ $file == *.log ]] corresponde a “app.log”. Colocar esse padrão entre aspas o tornaria literal. Essa sintaxe exige o Bash; dash não a implementa.

Principais conclusões

  • Um teste informa verdadeiro com o código 0 e falso com o código 1.
  • Coloque espaços ao redor de [ e de seus operadores e feche com ].
  • Testes de arquivo distinguem existência, tipo e acesso.
  • A igualdade de strings compara texto; operadores numéricos comparam valores inteiros.
  • Use -gt e -lt para números, não símbolos de redirecionamento isolados.
  • A negação inverte um teste; && exige ambas as condições.
  • [[ ... ]] do Bash aceita padrões e evita a separação de palavras.

4.2 Escolher ações com if, elif, else e case

Condições se tornam úteis quando selecionam ações. Um bloco if escolhe um ramo com base nos resultados de comandos. Um bloco case seleciona um ramo comparando um valor com padrões. Ambos tornam visíveis as ações disponíveis no script.

Deixe um comando escolher um ramo
if grep -q ERROR app.log; then
  echo "Errors found"
else
  echo "No successful match"
fi

if executa o comando e entra no primeiro ramo quando ele retorna 0. Caso contrário, entra em else. A própria busca é a condição; não é necessário executá-la, imprimir algo e depois examinar $?. Um erro de grep também retorna um valor diferente de zero, portanto este exemplo descreve o ramo else como ausência de correspondência bem-sucedida, não como prova de que o arquivo não contém erros.

then deve iniciar um novo comando: coloque-o na linha seguinte ou após um ponto e vírgula. fi fecha o bloco. A falta de fi muitas vezes produz um erro de sintaxe de fim de arquivo porque o Bash ainda está esperando o fechamento do bloco.

Ordene condições sobrepostas

elif adiciona um teste executado apenas quando os testes anteriores falharam. Para uma porcentagem inteira de uso de disco:

if [ "$usage" -ge 90 ]; then
  echo "CRITICAL: disk ${usage}% full"
elif [ "$usage" -ge 75 ]; then
  echo "WARNING: disk ${usage}% full"
else
  echo "OK: disk ${usage}% full"
fi

Com usage=82, o primeiro teste falha e o segundo é bem-sucedido, produzindo “WARNING: disk 82% full”. Com 95, o primeiro ramo é executado e o ramo de aviso é ignorado. Se o teste de 75 viesse primeiro, 95 corresponderia a ele e nunca chegaria ao teste crítico. Organize intervalos sobrepostos para que a condição mais restritiva seja verificada primeiro.

Apenas o primeiro ramo bem-sucedido é executado. else não precisa de condição e trata o que resta. Tanto elif quanto else podem ser omitidos quando a tarefa não precisa deles.

Compare um valor com case
case "$1" in
  start) echo "Starting" ;;
  stop) echo "Stopping" ;;
  y|Y|yes) echo "Confirmed" ;;
  *) echo "Usage: $0 start|stop|y|Y|yes" >&2; exit 2 ;;
esac

Cada padrão termina com ), cada ramo termina com ;; e esac fecha o bloco. O | dentro de um padrão fornece alternativas. O * final corresponde a qualquer valor e fica por último porque abrange todos eles.

case usa padrões de nomes de arquivo, não expressões regulares. *.jpg corresponde a um valor terminado em .jpg. [0-9]* corresponde a um valor cujo primeiro caractere é um dígito; o * pode corresponder a qualquer texto seguinte, portanto também corresponde a “7draft”. Isso não prova que um valor inteiro contenha apenas dígitos.

Escolha a estrutura adequada

Use case quando uma entrada, como um subcomando ou uma resposta, tiver várias formas identificadas. Use if quando as condições examinarem coisas diferentes, como a existência de um arquivo e se uma contagem ultrapassa um limite. Uma correspondência de padrão verifica os caracteres de um valor; um teste de arquivo verifica o caminho no disco. Um nome terminado em .log pode corresponder a um padrão mesmo quando esse arquivo não existe.

Principais conclusões

  • if escolhe um ramo pelo código de saída de um comando; qualquer comando pode ser uma condição.
  • Testes elif só são executados após a falha das condições anteriores.
  • Ordene limites sobrepostos do mais restritivo ao mais abrangente.
  • case seleciona o primeiro padrão correspondente e usa ;; para encerrar cada ramo.
  • Uma correspondência de padrão não comprova que um arquivo existe.

4.3 Repetir comandos para itens de listas e arquivos com for

Um laço for fornece ao mesmo corpo de comandos um novo valor a cada passagem. A lista pode conter palavras literais, nomes de arquivo correspondentes, um intervalo de números ou os argumentos do script. O Bash atribui um item da lista à variável do laço antes de executar o corpo.

Percorra uma lista fixa
for host in web1 web2 db1; do
  echo "Checking $host"
done

A primeira passagem tem host=web1, a segunda host=web2 e a terceira host=db1. O laço imprime três linhas. do abre o corpo e done o fecha. A variável permanece disponível após o laço, contendo seu último valor atribuído.

Um laço também pode acumular um resultado:

total=0
for n in 4 8 15; do
  total=$(( total + n ))
done
echo "$total"

O total armazenado muda de 0 para 4, depois 12 e depois 27. Inicialize o total antes do laço para que a primeira soma tenha um valor inicial definido.

Percorra arquivos correspondentes
for f in *.log; do
  [ -f "$f" ] || continue
  gzip -- "$f"
done

O Bash expande o padrão para os nomes correspondentes antes de executar o corpo do laço. Cada nome de arquivo correspondente permanece como um item da lista, mesmo que contenha espaços. Colocar "$f" entre aspas dentro do corpo mantém esse item junto quando ele é passado a gzip. Aqui, o teste de arquivo comum também ignora diretórios com nomes terminados em .log.

Com as configurações padrão de expansão de nomes de arquivo do Bash, um *.log sem correspondência permanece literal. Um laço sem verificação seria executado uma vez com os caracteres *.log e o comando falharia. [ -e "$f" ] || continue ignora caminhos inexistentes; use -f quando quiser apenas arquivos comuns.

Não construa um laço de nomes de arquivo a partir de $(ls). Sua saída é texto, portanto a separação de palavras pode transformar “my report.txt” em dois itens da lista. Um padrão já produz os nomes de arquivo com seus limites intactos.

Crie um novo nome a partir de cada nome antigo
for f in *.jpeg; do
  [ -f "$f" ] || continue
  mv -- "$f" "${f%.jpeg}.jpg"
done

${f%.jpeg} remove a terminação .jpeg do valor. Para “beach day.jpeg”, o destino se torna “beach day.jpg”. Os dois argumentos entre aspas mantêm ambos os caminhos intactos. -- informa a mv que os argumentos seguintes são nomes, mesmo que um comece com -. Use uma pasta de destino sem nomes conflitantes ao experimentar o exemplo, pois mv pode substituir um destino existente.

Conte em um intervalo

for i in {1..5} fornece os números de 1 a 5. O Bash expande as chaves antes de expandir variáveis, portanto {1..$n} não produz um intervalo de comprimento variável. Para um limite armazenado, use a forma aritmética:

for (( i = 1; i <= n; i++ )); do
  echo "$i"
done

A primeira expressão inicializa o contador, a do meio o testa antes de cada passagem e a última o atualiza. for i in $(seq 1 "$n") também produz uma lista de números para um limite inteiro positivo adequado. A substituição intencionalmente sem aspas fornece números separados.

Para argumentos, for arg in "$@" fornece um item por argumento original. A forma mais curta for arg; do significa a mesma coisa, incluindo a preservação de espaços dentro de cada argumento.

Principais conclusões

  • Um laço for executa seu corpo uma vez por item da lista.
  • Padrões de nomes de arquivo fornecem nomes completos; coloque a variável do laço entre aspas no corpo.
  • Um padrão sem correspondência permanece literal nas configurações padrão do Bash, portanto faça verificações em laços de arquivos.
  • Evite laços de nomes de arquivo construídos a partir de $(ls).
  • Intervalos entre chaves são definidos antes da expansão de variáveis; use um laço aritmético para um limite variável.
  • "$@" preserva os limites dos argumentos originais.

4.4 Repetir comandos até que uma condição mude com while e until

Algumas repetições terminam quando uma condição muda, não quando uma lista acaba. while e until testam a condição antes de cada passagem. O corpo de while é executado enquanto sua condição é bem-sucedida; o corpo de until é executado enquanto sua condição falha. Qualquer um dos laços pode ser executado zero vezes.

Atualize aquilo de que a condição depende
i=1
while [ "$i" -le 3 ]; do
  echo "Attempt $i"
  i=$(( i + 1 ))
done

A condição primeiro vê 1, depois 2 e depois 3. O corpo imprime esses três números de tentativa e aumenta o contador a cada vez. Após a atualização para 4, o teste seguinte falha e o laço termina. Se a atualização estivesse ausente, i permaneceria em 1 e o laço continuaria executando. Ctrl+C interrompe um laço em primeiro plano que esteja em execução.

Para aguardar um arquivo:

until [ -f /tmp/export.done ]; do
  sleep 5
done

Se o arquivo já existir, o corpo do laço nunca será executado. Caso contrário, sleep 5 pausa por cinco segundos antes da próxima verificação. Uma pausa impede que o laço teste continuamente e desperdice tempo do processador.

Leia registros como linhas
while IFS= read -r line; do
  echo "Host: $line"
done < hosts.txt

read fornece uma linha a cada passagem e retorna um código de falha no fim do arquivo. IFS= preserva espaços no início e no fim da linha; -r mantém barras invertidas. O redirecionamento de entrada após done fornece dados a todo o laço, não apenas ao comando final.

Uma linha como “web1 production” permanece como um valor. for line in $(cat hosts.txt) separaria em espaços, tabulações e caracteres de nova linha, tratando essas duas palavras como iterações separadas. Essa forma não consegue preservar registros arbitrários baseados em linhas.

Mantenha as alterações após o laço

Um pipe para um laço, como cat hosts.txt | while read -r line; do ...; done, normalmente executa o laço em um processo filho no Bash. Um contador alterado ali é perdido para o processo pai quando o filho termina. Redirecione o arquivo para o laço quando comandos posteriores precisarem de seus valores acumulados:

count=0
while IFS= read -r line; do
  count=$(( count + 1 ))
done < hosts.txt
echo "$count"

Isso processa linhas terminadas por um caractere de nova linha e mantém a contagem atualizada no shell atual. Nenhum encadeamento cria um processo filho para o laço.

Trate o registro final e saídas antecipadas

Um arquivo pode terminar com texto, mas sem um caractere final de nova linha. read armazena esse último texto, mas informa falha, portanto um while read simples não entra em seu corpo para esse registro. Adicione um segundo teste para aceitar o texto não vazio armazenado:

while IFS= read -r line || [ -n "$line" ]; do
  echo "Host: $line"
done < hosts.txt

break sai do laço imediatamente. continue pula os comandos restantes na passagem atual e retorna à próxima verificação da condição. Portanto, um laço while true precisa de um break, um exit ou um sinal para terminar; ele pode servir a um menu que é encerrado quando a entrada é “q”. Coloque uma atualização antes de qualquer continue que a ignoraria em um laço com contador, ou essa passagem poderá se repetir indefinidamente.

Principais conclusões

  • while repete após sucesso; until repete após falha.
  • Ambos os laços testam a condição antes de entrar em seus corpos.
  • Atualize um contador ou pause um laço de verificações para que ele avance sem espera ocupada.
  • IFS= read -r preserva espaços e barras invertidas em entradas baseadas em linhas.
  • Redirecione um arquivo para o laço para manter as variáveis alteradas no shell atual.
  • Um teste adicional de string não vazia preserva um registro final sem caractere de nova linha.
  • break sai de um laço; continue pula para sua próxima passagem.
5

Passar argumentos para scripts

Argumentos de linha de comando permitem que um script sirva a várias tarefas sem editar seu código. Você lerá valores individuais, preservará uma lista completa de argumentos e processará opções iniciais. Antes de começar o trabalho, conte e valide as entradas, explique uma chamada correta e forneça valores padrão para entradas opcionais. O resultado pode ser executado em um prompt ou sem acompanhamento, com mensagens claras e um código de saída quando a entrada não puder ser usada.

5.1 Ler parâmetros posicionais e a quantidade de argumentos

Argumentos transformam um script com entrada fixa em um comando reutilizável. O Bash coloca as palavras após o nome do script em parâmetros posicionais. Seus limites são definidos pelo shell que faz a chamada, portanto as aspas importam tanto na chamada do script quanto no uso desses valores.

Identifique os parâmetros
./backup.sh /home/sam/docs /mnt/usb

Dentro do script, $0 é ./backup.sh, $1 é /home/sam/docs e $2 é /mnt/usb. $# é 2, a quantidade de argumentos. O script pode usar cp -r "$1" "$2" para copiar a pasta de origem para o destino sem fixar nenhum dos caminhos no código.

$0 descreve o nome usado para iniciar o script; ele não é contado em $#. Com ./greet.sh Ana "Lee Kim", o primeiro argumento é “Ana” e o segundo é “Lee Kim”. Sem as aspas ao redor do segundo nome, o script receberia três argumentos.

Use chaves após o nono argumento

$1 a $9 nomeiam os primeiros nove parâmetros posicionais. O décimo precisa de ${10}, e as posições seguintes usam a mesma forma. $10 significa a expansão de $1 seguida do caractere literal 0. Se o primeiro argumento for “Ana”, $10 se torna “Ana0” mesmo quando há um décimo argumento.

Um parâmetro omitido é expandido para texto vazio nas configurações normais. Com dois argumentos, $3 está ausente; sob set -u, expandi-lo causa um erro de variável não definida. Verifique a quantidade antes de ler posições obrigatórias ou use uma expansão que forneça um valor padrão.

Preserve todos os limites dos argumentos

Suponha que um script receba "a b" e c. Compare:

ExpansãoPalavras repassadas
"$@"Duas: “a b” e “c”.
"$*"Uma: “a b c”, com o separador usual de espaço.
$@Três: “a”, “b” e “c” na separação normal.

"$@" é a escolha usual para repassar argumentos:

for arg in "$@"; do
  echo "Argument: $arg"
done

O laço é executado duas vezes para essa chamada, uma vez por argumento original. Sem argumentos, ele é executado zero vezes. Colocar "$@" entre aspas duplas tem um significado especial: cada parâmetro posicional permanece como uma palavra separada, portanto as aspas não unem toda a lista em uma palavra.

"$*" une valores usando o primeiro caractere de IFS, que normalmente é um espaço. Isso pode ser útil para uma única string de exibição, mas perde os limites individuais de que um comando posterior pode precisar.

Processe parâmetros com shift

shift remove o primeiro parâmetro posicional, desloca os seguintes e reduz $#. Na chamada de cópia de segurança, um shift faz $1 se tornar /mnt/usb e a contagem se tornar 1. shift 2 remove os dois primeiros parâmetros de uma vez.

Isso permite criar um laço que examina $1, o trata e depois executa shift antes da próxima passagem. Verifique se restam argumentos com [ "$#" -gt 0 ]; caso contrário, o script pode ler um valor ausente ou tentar deslocar além dos argumentos disponíveis. O deslocamento não altera $0 e não pode alterar a lista de argumentos do shell pai que iniciou o script.

Principais conclusões

  • $0 é o nome usado na chamada, enquanto $1 em diante armazenam argumentos.
  • $# conta os argumentos, mantendo espaços entre aspas dentro de um argumento.
  • Use ${10} para o décimo argumento; $10 é $1 seguido de 0.
  • "$@" preserva os argumentos separadamente, enquanto "$*" os une.
  • shift remove parâmetros iniciais e altera as posições restantes.

5.2 Verificar argumentos, mostrar instruções de uso e definir valores padrão

Um script deve confirmar que sua entrada pode ser usada antes de começar o trabalho. Verifique a quantidade de argumentos e depois seu significado. Entradas opcionais podem ter valores padrão; entradas obrigatórias ausentes precisam de uma mensagem clara e de um código de saída diferente de zero.

Explique a chamada esperada
if [ "$#" -ne 2 ]; then
  echo "Usage: $0 SOURCE DEST" >&2
  exit 2
fi

Isso verifica a quantidade antes de expandir $1 ou $2, portanto também funciona sob set -u. A mensagem de uso vai para a saída de erro padrão. Maiúsculas nomeiam valores fornecidos pelo usuário, [DEST] significaria um destino opcional e FILE... significa um ou mais argumentos de arquivo. Uma opção de ajuda como -h normalmente imprime as instruções de uso e sai com 0 porque pedir ajuda é um uso bem-sucedido.

A quantidade de argumentos, por si só, não mostra se uma origem pode ser usada. [ -d "$1" ] verifica se há um diretório existente. Um teste de arquivo comum pode selecionar arquivos, mas a própria operação ainda precisa de uma verificação de resultado: permissões ou outros erros podem impedir uma leitura.

Use um valor padrão ou exija um valor
logdir=${1:-/var/log}
src=${1:?Usage: backup.sh SOURCE [DEST]}

A primeira forma usa /var/log quando o primeiro parâmetro está ausente ou vazio. A segunda interrompe um script não interativo em ambos os casos e imprime sua mensagem na saída de erro padrão. Os dois-pontos fazem parte de ambas as formas. Um valor padrão é usado para essa expansão; ${1:-...} não adiciona um argumento à lista de parâmetros posicionais.

Registre falhas parciais

Um script de contagem de arquivos pode continuar após uma entrada inválida e ainda informar que a tarefa inteira ficou incompleta:

#!/bin/bash
if [ "$#" -eq 0 ]; then
  echo "Usage: $0 FILE..." >&2
  exit 2
fi
status=0
for f in "$@"; do
  if [ -f "$f" ]; then
    if lines=$(wc -l < "$f"); then
      echo "$f: $lines lines"
    else
      echo "$f: could not count lines" >&2
      status=1
    fi
  else
    echo "$f: not a regular file" >&2
    status=1
  fi
done
exit "$status"

Para notes.txt missing.txt, o script imprime a contagem do arquivo legível e informa o arquivo ausente, depois sai com 1. A atribuição é testada diretamente, portanto uma falha de leitura não se transforma em uma contagem vazia bem-sucedida. Um sucesso posterior nunca redefine o indicador de falha armazenado para 0.

Trate opções simples antes dos nomes de arquivo
verbose=0
while [ "$#" -gt 0 ]; do
  case "$1" in
    -v) verbose=1; shift ;;
    -h) echo "Usage: $0 [-v] FILE..."; exit 0 ;;
    --) shift; break ;;
    -*) echo "Unknown option: $1" >&2; exit 2 ;;
    *) break ;;
  esac
done

Cada opção reconhecida é consumida com shift. O primeiro argumento comum encerra a análise de opções; -- também a encerra e é consumido. O "$@" restante contém os nomes de arquivo, incluindo um nome que começa com - após --. O getopts do Bash aceita uma análise mais completa de opções curtas.

Um script sem acompanhamento precisa de todas as entradas obrigatórias em argumentos, valores padrão ou configuração. read pode bloquear a execução enquanto espera um terminal ou falhar imediatamente no fim do arquivo. Substituir um argumento ausente por um prompt deixaria uma tarefa agendada sem uma forma confiável de continuar.

Principais conclusões

  • Valide a quantidade antes de expandir argumentos obrigatórios.
  • Uma mensagem de uso nomeia entradas obrigatórias, opcionais e repetíveis.
  • ${1:-value} fornece um valor padrão; ${1:?message} rejeita um valor ausente ou vazio.
  • Verifique o resultado da operação mesmo após verificar o tipo de arquivo da entrada.
  • Preserve um código geral de falha ao continuar processando várias entradas.
  • Consuma opções com shift e respeite -- como o fim das opções.
6

Agendar a execução automática de scripts

Um script sem acompanhamento precisa de um agendamento e de uma forma de inspecionar seus resultados. O cron expressa horários correspondentes em uma linha; o systemd associa um serviço a um temporizador. Você lerá as duas formas, fornecerá o ambiente necessário à tarefa e manterá sua saída disponível. Verificar separadamente a próxima ativação e o resultado da última tarefa ajuda a distinguir um agendamento ativo de um trabalho que de fato foi bem-sucedido.

6.1 Agendar tarefas com cron

O cron inicia comandos nos horários correspondentes. O crontab de cada usuário armazena seu agendamento, e as tarefas são executadas com a identidade desse usuário. Um script agendado precisa de uma expressão de tempo correta e de um ambiente que forneça seus caminhos, entradas e destino de saída.

Leia os cinco campos

Use crontab -e para editar sua tabela e crontab -l para inspecioná-la. crontab -r exclui toda a tabela sem perguntar; use o editor para remover uma única tarefa.

Campo, em ordemValores
Minuto0–59
Hora0–23
Dia do mês1–31
Mês1–12
Dia da semana0–7; 0 e 7 significam domingo
30 2 * * * /home/sam/bin/backup.sh

Isso executa todos os dias às 02:30. Asteriscos aceitam todos os valores de um campo. 0 9 * * 1-5 seleciona 09:00 nos dias úteis, e 0 0 1 * * seleciona a meia-noite no primeiro dia de cada mês. Os horários usam o fuso horário do sistema, a menos que a configuração do cron especifique outro fuso compatível.

Combine intervalos, listas e passos

Uma vírgula lista valores: 1,15 no campo de dia do mês seleciona o primeiro e o décimo quinto dia. Um hífen indica um intervalo, e / introduz um passo. */15 no campo de minutos seleciona 0, 15, 30 e 45.

*/20 8-10 * * * seleciona três minutos em cada uma de três horas: nove execuções diárias, começando às 08:00 e terminando às 10:40. Os passos recomeçam dentro de seu campo. */45 executa no minuto 0 e no minuto 45 de cada hora; o intervalo até o minuto 0 da hora seguinte é de apenas 15 minutos.

Quando os campos de dia do mês e dia da semana estão ambos restritos, a correspondência de qualquer um deles basta. 0 12 13 * 5 seleciona o meio-dia no dia 13 e nas sextas-feiras, não apenas na sexta-feira 13. Os outros campos ainda precisam corresponder.

Strings especiais substituem os cinco campos: @hourly, @daily, @weekly, @monthly, @yearly e @reboot. @daily significa meia-noite, enquanto @reboot executa uma vez na inicialização.

Forneça caminhos e mantenha a saída

O cron normalmente usa /bin/sh para sua linha de comando, um PATH curto e nenhuma configuração de inicialização de shell interativo. O próprio shebang Bash de um script executável ainda seleciona o Bash. Use caminhos absolutos para o script e seus arquivos ou defina PATH no início do crontab.

30 2 * * * /home/sam/bin/backup.sh >> /home/sam/backup.log 2>&1

A tarefa acrescenta ambos os fluxos de saída ao log. Sem redirecionamento, o cron envia a saída por e-mail quando o correio está configurado, inclusive por meio de MAILTO; caso contrário, a saída pode ser perdida. Um sinal de porcentagem tem uma função especial em um comando do crontab: ele inicia uma nova linha e a entrada subsequente. Use escape em um formato de data ali, como em date +\%F. Um comando de data dentro de um script separado usa %F normalmente.

Distinga agendamentos do sistema e tarefas recuperadas

/etc/crontab e os arquivos em /etc/cron.d/ adicionam um campo de usuário após os cinco campos de tempo. Por exemplo, 30 2 * * * root /usr/local/bin/backup.sh é executado como root. Não adicione esse campo de usuário a um crontab pessoal.

Muitas distribuições também executam arquivos executáveis elegíveis em /etc/cron.daily/, /etc/cron.weekly/ e /etc/cron.monthly/. As regras padrão de nomenclatura de run-parts no Debian ignoram nomes que contêm pontos, portanto use backup-notes, não backup-notes.sh, nesses locais. O cron perde horários que passam enquanto o computador está desligado. O Anacron pode executar tarefas periódicas diárias, semanais ou mensais perdidas após a inicialização.

Principais conclusões

  • Um crontab pessoal tem cinco campos de tempo seguidos diretamente por um comando.
  • Listas, intervalos e passos selecionam valores dentro de cada campo.
  • Quando os campos de dia do mês e dia da semana estão restritos, basta que um deles corresponda.
  • Use caminhos absolutos e um log de saída para tarefas sem acompanhamento.
  • Use escape em % em um comando do crontab, inclusive em formatos de data.
  • Crontabs do sistema adicionam um campo de usuário; pastas periódicas também aplicam regras de elegibilidade.
  • O cron perde execuções enquanto a máquina está desligada; o anacron permite recuperar tarefas periódicas.

6.2 Agendar tarefas com temporizadores do systemd

O systemd separa o trabalho de seu agendamento. Uma unidade de serviço descreve o comando a ser executado. Uma unidade de temporizador descreve quando iniciá-lo. Por padrão, backup.timer ativa backup.service, usando o nome-base compartilhado para conectar o par.

Escreva o serviço e o agendamento de calendário

Coloque estas unidades de sistema em /etc/systemd/system/:

# backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Type=oneshot é adequado para um script que é executado uma vez e termina. Use um caminho de comando absoluto e torne o script executável com um shebang Bash. O temporizador fornece o agendamento:

# backup.timer
[Unit]
Description=Run backup.service daily at 02:30

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar corresponde a datas e horários. Aqui, a data com caracteres curinga aceita todos os dias. Persistent=true habilita a recuperação de execuções após a inatividade do temporizador: se pelo menos uma execução de calendário foi perdida, ele inicia o serviço uma vez na reativação. Ele não repete cada execução perdida.

Carregue e ative o temporizador
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer

Recarregue após criar ou alterar arquivos de unidade. enable --now inicia o temporizador imediatamente e o habilita para inicializações futuras. Habilitar apenas o serviço não cria um agendamento. Teste o trabalho separadamente com sudo systemctl start backup.service.

Escolha um horário ou tempo decorrido
ConfiguraçãoAgendamento
OnCalendar=Mon..Fri *-*-* 09:00:00Dias úteis às 09:00
OnCalendar=*:0/15Minutos 0, 15, 30 e 45 de cada hora
OnBootSec=10minDez minutos após a inicialização
OnUnitActiveSec=1hUma hora após a última ativação do serviço

Expressões de calendário podem usar daily para a meia-noite de cada dia ou weekly para segunda-feira à meia-noite. Verifique uma expressão com systemd-analyze calendar "Mon..Fri 09:00" para ver sua interpretação e próxima ocorrência.

As duas últimas configurações são temporizadores monotônicos: eles medem o tempo decorrido desde um evento. Combine-os para uma primeira execução após a inicialização e ativações posteriores a cada hora. Persistent=true se aplica a temporizadores de calendário; ele não adiciona recuperação de calendário a temporizadores monotônicos.

Inspecione o agendamento e os resultados separadamente

systemctl list-timers mostra as próximas e as últimas ativações. systemctl status backup.service mostra o resultado do serviço, e journalctl -u backup.service mostra sua saída e seus erros. Uma próxima execução listada comprova que um agendamento está ativo, não que a tarefa anterior do script foi bem-sucedida.

Temporizadores têm uma janela de disparo. AccuracySec tem como padrão um minuto; AccuracySec=1s reduz a janela de agrupamento. RandomizedDelaySec adiciona deliberadamente um atraso aleatório para distribuir o trabalho entre máquinas. Essas configurações não garantem um segundo exato de início sob carga.

Execute um temporizador próprio do usuário

Arquivos de unidade de usuário ficam em ~/.config/systemd/user/, e os comandos usam systemctl --user, incluindo daemon-reload, enable --now e list-timers. Um gerenciador de usuário normalmente é executado durante a sessão desse usuário. Um administrador pode habilitar a permanência sem sessão ativa com loginctl enable-linger username para mantê-lo disponível sem login.

O cron precisa de uma linha compacta de tempo e funciona sem systemd. Temporizadores acrescentam um resultado de serviço e um diário de registros, recuperação de execuções de calendário e mais controle. Nenhum dos dois normalmente carrega ~/.bashrc; ambos precisam de scripts que funcionem com caminhos explícitos e sem prompts interativos.

Principais conclusões

  • O serviço determina o que executar; o temporizador determina quando.
  • Recarregue unidades alteradas e habilite o .timer com --now.
  • Temporizadores de calendário seguem o relógio; temporizadores monotônicos medem o tempo desde eventos.
  • Persistent=true recupera uma vez o trabalho de calendário perdido na reativação.
  • Verifique tanto a próxima ativação do temporizador quanto o estado e o diário de registros do serviço.
  • Temporizadores de usuário precisam de um gerenciador de usuário em execução, com permanência habilitada para execuções sem sessão.

Exercícios resolvidos de Scripts de shell

6 Lições Interativas

1

Salvar um relatório de pasta que possa ser repetido

9 passos
Criar um pequeno relatório em Bash, executá-lo pelo caminho e distinguir a execução da execução no shell atual.
  1. 1
    IntroduçãoReúna uma tarefa repetida em um só lugar

    Você costuma verificar onde está, listar uma pasta e imprimir uma mensagem de conclusão. Salvar os comandos permite repetir sua ordem.

    Um script é um arquivo de texto simples lido por um interpretador. Você criará um pequeno relatório, selecionará o Bash explicitamente e o executará em um shell filho. O nome do arquivo, a permissão de execução e o local respondem, cada um, a uma pergunta diferente sobre como iniciá-lo.

  2. 2
    ExemploEscreva os comandos em ordem

    Salve isto como folder-report.sh em um editor de texto simples:

    #!/bin/bash
    pwd
    ls
    echo "Report finished"
    

    O shebang seleciona o Bash quando o arquivo é executado diretamente. O comentário explica a tarefa, mas não é executado. O Bash executa pwd, ls e echo nessa ordem. A terminação .sh ajuda o leitor a reconhecer o arquivo; ela não seleciona o interpretador.

  3. 3
    DesafioVerifique o que seleciona a linguagem

    Um colega altera a primeira linha para #!/bin/sh e depois adiciona [[ ... ]]. O arquivo ainda termina em .sh. Por que ele pode falhar?

    ---reveal---

    O shebang seleciona sh, que pode ser dash e talvez não entenda [[ ... ]] do Bash. A extensão não escolhe a linguagem. Restaure um shebang Bash para recursos do Bash, com #! no início da primeira linha.

  4. 4
    ExplicaçãoLeia o arquivo com o Bash primeiro

    Execute bash folder-report.sh. Isso inicia o Bash e passa a ele o arquivo de script legível; a permissão de execução no script não é necessária. O interpretador escolhido já é o Bash, portanto o shebang não faz essa escolha.

    Você deve ver um caminho, uma listagem e a mensagem “Report finished”. Os caminhos relativos usados pelos comandos dentro do script são resolvidos a partir de seu diretório de trabalho, não automaticamente da pasta do arquivo de script.

  5. 5
    ExemploPermita a execução direta

    Adicione permissão de execução para o proprietário e execute o caminho exato:

    chmod u+x folder-report.sh
    ./folder-report.sh
    

    ./ indica o diretório atual. A execução direta usa o shebang do arquivo. Se o arquivo for legível, mas não executável, o comando anterior com bash pode funcionar enquanto este falha com “Permission denied.” A permissão e a seleção do interpretador são partes distintas da inicialização.

  6. 6
    DicaEncontre o script pelo nome

    Digitar folder-report.sh sem barra pede ao Bash que procure no PATH. O diretório atual normalmente não está nessa lista.

    Um diretório bin pessoal permite que você execute o script a partir de outras pastas quando ele está no PATH. Examine echo "$PATH" e use command -v folder-report.sh para ver qual executável esse nome seleciona. Se uma cópia antiga vier primeiro no PATH, editar uma cópia mais recente em outro lugar não mudará o que esse nome executa.

  7. 7
    DesafioMantenha uma mudança de diretório no shell certo

    O script agora começa com cd /var/log. Após o término de ./folder-report.sh, seu terminal mudou para lá? Como um arquivo de configuração poderia mudá-lo?

    ---reveal---

    O script executado roda em um shell filho, portanto sua mudança de diretório não move o terminal pai. Executar um arquivo no shell atual com source ./settings.sh roda seus comandos nesse shell e pode mudar o diretório da sessão. Essa execução usa a linguagem do shell atual.

  8. 8
    DesafioDiagnostique a inicialização antes de editar comandos

    Um relatório legível funciona com bash folder-report.sh. A execução direta informa “Permission denied”, e digitar apenas seu nome informa “command not found”. Quais dois problemas de inicialização devem ser verificados?

    ---reveal---

    Verifique a permissão de execução do script para a execução direta. Depois, verifique o PATH ou use o caminho explícito com ./ para localizá-lo. Um shebang Bash válido seleciona o interpretador, mas não pode conceder permissões nem colocar o arquivo no PATH.

  9. 9
    RecapitulaçãoUma inicialização envolve várias escolhas distintas

    O arquivo contém a sequência de comandos. O interpretador lê sua linguagem, as permissões permitem a execução direta e o PATH ou uma barra localiza o arquivo.

    Um script executado funciona em um shell filho. Um arquivo de configuração executado no shell atual funciona no shell já aberto, portanto suas atribuições e mudanças de diretório podem permanecer nessa sessão.

2

Criar um nome de relatório com data sem perder espaços

11 passos
Acompanhar valores durante a atribuição, a proteção com aspas, a captura de comandos e cálculos com números inteiros.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoAcompanhe um valor até um comando
  2. 2
    ExemploArmazene um destino com várias palavras
  3. 3
    ConexãoPasse a configuração a um processo filho
  4. 4
    DesafioSepare um nome de seu sufixo
  5. 5
    ExemploPreserve o caminho armazenado
  6. 6
    DesafioEscolha texto fixo ou texto variável
  7. 7
    ExemploCapture uma data para o nome
  8. 8
    ExemploCalcule antes de inserir o valor
  9. 9
    DesafioLocalize a fração perdida
  10. 10
    DesafioCombine o caminho e o valor capturado
  11. 11
    RecapitulaçãoDistinga as três funções
3

Impedir que uma busca malsucedida resulte em um relatório bem-sucedido

10 passos
Inspecionar um encadeamento, preservar a falha e escolher a verificação de depuração adequada.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoTrate o resultado como parte da tarefa
  2. 2
    ExemploVeja a falha oculta no início do encadeamento
  3. 3
    Ideia-chaveFaça o encadeamento informar sua falha
  4. 4
    DesafioSalve o código que importa
  5. 5
    ExemploTrate explicitamente o trabalho malsucedido
  6. 6
    ExplicaçãoEscolha entre verificação de sintaxe e rastreamento de execução
  7. 7
    ExplicaçãoEntenda as opções de erro como controles separados
  8. 8
    DesafioExplique por que este script continua
  9. 9
    DesafioMantenha informado quem chamou o script
  10. 10
    RecapitulaçãoLeia tanto os dados quanto o resultado
4

Inspecionar arquivos recebidos e ler seus registros

15 passos
Usar testes, ramos ordenados e laços para processar arquivos sem perder nomes ou linhas.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoDeixe cada tipo de entrada escolher sua próxima etapa
  2. 2
    ExemploEscolha um teste para o tipo do caminho
  3. 3
    ExplicaçãoCompare valores da maneira adequada
  4. 4
    DesafioInterprete um teste de arquivo negado
  5. 5
    ExemploSelecione uma ação com o resultado de um comando
  6. 6
    DesafioAcompanhe limites sobrepostos
  7. 7
    ExplicaçãoAssocie uma palavra de ação com case
  8. 8
    ExemploForneça um arquivo por passagem a um laço com padrão
  9. 9
    DesafioExplique o caso da pasta vazia
  10. 10
    DicaEscolha um limite numérico variável
  11. 11
    ExemploLeia um registro sem separar seus espaços
  12. 12
    DesafioMantenha o último registro sem caractere de nova linha
  13. 13
    ConexãoAguarde sem verificar continuamente
  14. 14
    DesafioDiagnostique um total que permanece em zero
  15. 15
    RecapitulaçãoEscolha a estrutura adequada aos dados
5

Aceitar arquivos de entrada e informar falhas parciais

10 passos
Validar um comando reutilizável, consumir uma opção e manter o resultado geral.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoFaça da entrada parte da chamada do comando
  2. 2
    ExemploInspecione os limites da chamada
  3. 3
    ExplicaçãoConsuma a opção inicial
  4. 4
    DesafioMantenha um argumento vazio na contagem
  5. 5
    ExemploRejeite uma chamada sem arquivos de entrada
  6. 6
    ExplicaçãoEscolha um valor padrão apenas para entrada opcional
  7. 7
    ExemploVerifique a própria operação de leitura
  8. 8
    DesafioLembre-se da falha anterior
  9. 9
    DesafioEncerre a análise antes de um nome de arquivo com hífen
  10. 10
    RecapitulaçãoDê aos comandos reutilizáveis um contrato confiável
6

Agendar um relatório e verificar sua última execução

12 passos
Ler expressões do cron, criar um par de temporizador e serviço e distinguir o horário agendado do sucesso da tarefa.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoAgende apenas trabalhos com entrada completa
  2. 2
    ExemploLeia uma entrada de crontab pessoal
  3. 3
    DesafioAcompanhe um passo de minutos na mudança de hora
  4. 4
    DicaDê à tarefa um destino de saída
  5. 5
    ConexãoDistinga uma execução perdida de uma execução malsucedida
  6. 6
    ExemploColoque o trabalho em um serviço
  7. 7
    ExemploColoque o horário no temporizador correspondente
  8. 8
    ExplicaçãoCarregue as alterações e habilite o agendamento
  9. 9
    DesafioVerifique o resultado e também o próximo horário
  10. 10
    ExplicaçãoConte o tempo a partir de um evento quando necessário
  11. 11
    DesafioEscolha a recuperação após um período desligado
  12. 12
    RecapitulaçãoInspecione o agendamento e a tarefa separadamente

Questões de Scripts de shell

50 Questões de Prática em 5 conjuntos

Conjunto 1: Acompanhar valores, registros e agendamentos10 Questões de Prática

Questão 1 de 10

Um script executado diretamente informa /bin/bash^M: bad interpreter, mas /bin/bash existe. Qual alteração no arquivo resolve o problema indicado?
  1. Alterar a extensão do script de .sh para .bash.
  2. Mover o script para um diretório no PATH.
  3. Adicionar permissão de execução para o proprietário.
  4. Converter o script para terminadores de linha do Unix.
Mostrar respostaOcultar resposta
Resposta: D
^M indica um retorno de carro de terminadores de linha do Windows, fazendo o caminho do interpretador ser diferente de /bin/bash. Converter o arquivo para terminadores de linha do Unix remove esse caractere extra. A permissão de execução não corrige caracteres dentro do caminho do interpretador, e o PATH não resolve um caminho fixo no shebang.

Questão 2 de 10

Como você atribui o texto “North Hall” a uma variável Bash chamada site?
  1. site="North Hall"
  2. site = "North Hall"
  3. $site="North Hall"
  4. site=North Hall
Mostrar respostaOcultar resposta
Resposta: A
A atribuição usa o nome da variável sem cifrão e não tem espaços ao redor de =. As aspas preservam as duas palavras como valor. Com espaços ao redor de =, o Bash trata site como um comando; sem aspas ao redor do valor, Hall se torna uma palavra de comando em vez de parte da atribuição.

Questão 3 de 10

Qual valor left=$(( 29 % 6 )) atribui?
  1. 4
  2. 4.83
  3. 5
  4. 1
Mostrar respostaOcultar resposta
Resposta: C
Quatro grupos inteiros de 6 usam 24, deixando resto 5. O operador % retorna esse resto. O quociente 4 viria da divisão inteira com /, enquanto a aritmética do Bash não produz um quociente decimal como 4,83 a partir dessa expressão.

Questão 4 de 10

Falta o done de fechamento em um script. Qual comando pode detectar esse problema de sintaxe sem executar o script?
  1. bash -x batch.sh
  2. bash -n batch.sh
  3. bash batch.sh
  4. source ./batch.sh
Mostrar respostaOcultar resposta
Resposta: B
bash -n lê o script e verifica sua estrutura de shell sem executar os comandos. Ele pode detectar um laço sem o done de fechamento. bash -x também lê o script, mas o executa com rastreamento, portanto comandos válidos anteriores podem ser executados antes que o problema de sintaxe seja encontrado.

Questão 5 de 10

Quais são os resultados de [ 06 = 6 ] e [ 06 -eq 6 ], nessa ordem?
  1. Verdadeiro, depois falso.
  2. Verdadeiro, depois verdadeiro.
  3. Falso, depois verdadeiro.
  4. Falso, depois falso.
Mostrar respostaOcultar resposta
Resposta: C
O primeiro teste compara texto, e “06” contém um zero inicial ausente de “6”, portanto é falso. O segundo compara valores inteiros e é bem-sucedido porque ambos representam seis. Tratar ambos os testes como comparações numéricas ignoraria a finalidade dos diferentes operadores.

Questão 6 de 10

Um diretório contém a.csv e late batch.csv, ambos arquivos comuns. Quais valores são usados em for f in *.csv; do echo "$f"; done?
  1. Dois itens: a.csv e late batch.csv.
  2. Três itens: a.csv, late e batch.csv.
  3. Um item: o padrão literal *.csv.
  4. Um item: a.csv late batch.csv.
Mostrar respostaOcultar resposta
Resposta: A
O padrão é expandido para nomes de arquivo correspondentes como itens separados e intactos, portanto o laço recebe dois nomes. O espaço dentro de “late batch.csv” não separa um nome produzido pela expansão de nomes de arquivo. Colocar "$f" entre aspas no corpo mantém esse valor junto quando ele é passado a um comando.

Questão 7 de 10

Um arquivo contém oak, um caractere de nova linha e depois elm sem um caractere final de nova linha. Qual contagem é impressa?

count=0
while IFS= read -r line; do
  count=$(( count + 1 ))
done < trees.txt
echo "$count"
  1. 0
  2. 2
  3. 3
  4. 1
Mostrar respostaOcultar resposta
Resposta: D
A primeira leitura obtém um registro terminado por um caractere de nova linha e entra no corpo, aumentando a contagem para 1. A segunda armazena “elm”, mas retorna falha no fim do arquivo, portanto o corpo é ignorado. O redirecionamento de entrada preserva a contagem atualizada; adicionar || [ -n "$line" ] também processaria o registro final e produziria 2.

Questão 8 de 10

Após a chamada ./task.sh -v "blue room" output.txt, o script executa shift. Quais são agora os valores de $1 e $#?
  1. -v e 2.
  2. blue room e 2.
  3. blue e 3.
  4. output.txt e 1.
Mostrar respostaOcultar resposta
Resposta: B
shift consome o primeiro argumento, “-v”, e desloca os dois argumentos restantes. O nome entre aspas se torna $1, e $# cai de 3 para 2. O espaço dentro do nome permanece intacto; o deslocamento não separa o texto nem consome também o segundo argumento.

Questão 9 de 10

Quantas vezes por dia */25 10-12 * * * é executado e quando ocorre sua última execução?
  1. 6 vezes; a última às 12:25.
  2. 8 vezes; a última às 12:55.
  3. 9 vezes; a última às 12:50.
  4. 9 vezes; a última às 13:00.
Mostrar respostaOcultar resposta
Resposta: C
O campo de minutos seleciona 0, 25 e 50, e o intervalo de horas inclui 10, 11 e 12. Três minutos selecionados em cada uma de três horas resultam em nove execuções, terminando às 12:50. Uma contagem contínua de 25 minutos entre horas estaria errada porque o passo recomeça dentro de cada hora.

Questão 10 de 10

Com a correspondência padrão de unidades, qual serviço é ativado por inventory.timer?
  1. inventory.service
  2. timer.service
  3. inventory.timer.service
  4. inventory.target
Mostrar respostaOcultar resposta
Resposta: A
Um temporizador normalmente ativa o serviço com o mesmo nome-base, portanto inventory.timer inicia inventory.service. O temporizador armazena o agendamento, enquanto o serviço define o trabalho. Acrescentar outra extensão ao nome completo do temporizador não identificaria a unidade correspondente padrão.
Conjunto 2: Ler e executar pequenos scripts Bash10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Em um crontab pessoal, qual agendamento 25 4 * * * /home/rae/bin/audit.sh especifica?
  1. Todos os dias às 04:25.
  2. Todos os dias às 25:04.
  3. A cada hora no minuto 4.
  4. No dia 4 às 00:25.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um script usa a sintaxe [[ ... ]] do Bash, mas sua primeira linha é #!/bin/sh. Nesta máquina, sh é dash. Qual primeira linha seleciona o interpretador pretendido?
  1. #!/bin/sh bash
  2. # /bin/bash
  3. #!/bin/bash
  4. #!/usr/bin/env sh
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um script pode ser lido por seu proprietário, mas não tem permissão de execução. Como o proprietário pode executar seus comandos Bash sem alterar essa permissão?
  1. ./audit.sh
  2. bash audit.sh
  3. chmod u-x audit.sh
  4. source bash audit.sh
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Com label="west side", quais argumentos printf '<%s>\n' "$label" formata?
  1. Um argumento: west side.
  2. Dois argumentos: west e side.
  3. Um argumento: o literal $label.
  4. Um argumento: o literal "west side".
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um script define file="shift notes.txt". Como ele deve copiar esse único arquivo para o diretório existente saved?
  1. cp '$file' saved/
  2. cp $file saved/
  3. cp "file" saved/
  4. cp "$file" saved/
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Um comando acabou de falhar com o código de saída 7. Qual atribuição preserva imediatamente esse resultado para uso posterior?
  1. result=$#
  2. result=$?
  3. result=$!
  4. result=0
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O caminho archive existe e é um diretório. Quais são os resultados de [ -f archive ] e [ -d archive ], nessa ordem?
  1. Verdadeiro, depois verdadeiro.
  2. Verdadeiro, depois falso.
  3. Falso, depois verdadeiro.
  4. Falso, depois falso.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

O que é impresso por este código?

used=14
limit=20
percent=$(( used * 100 / limit ))
if [ "$percent" -ge 60 ]; then
  used=$(( used + 2 ))
elif [ "$percent" -ge 70 ]; then
  used=$(( used + 5 ))
fi
echo "$used"
  1. 16
  2. 19
  3. 21
  4. 14
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um script é chamado com ./label.sh "East Wing" report.txt. Quais são os valores de $# e $2?
  1. 3 e Wing.
  2. 2 e East Wing.
  3. 3 e report.txt.
  4. 2 e report.txt.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um script Bash não interativo usa dir=${1:-/srv/logs}. Ele é chamado com um argumento que é uma string vazia entre aspas. Qual valor é atribuído?
  1. Uma string vazia.
  2. O texto literal ${1}.
  3. /srv/logs
  4. O script sai com um erro.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 3: Acompanhar dados em um script completo10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Um terminal Bash começa com zone=west. O arquivo settings.sh contém apenas zone=east. O terminal executa bash settings.sh, depois source ./settings.sh e depois bash -c 'echo "${zone:-unset}"'. A variável nunca foi exportada. O que o último comando imprime?
  1. east
  2. unset
  3. west
  4. Uma linha vazia.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Com name=archive, o que echo "${name}_ready" imprime?
  1. name_ready
  2. archive
  3. Uma linha vazia.
  4. archive_ready
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um script armazena completed=18 e total=32. Qual resultado inteiro é produzido por $(( completed * 100 / total ))?
  1. 56
  2. 0
  3. 57
  4. 56.25
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

O arquivo absent.log não existe. Qual código de saída chega a quem chamou o script?

#!/bin/bash
set -o pipefail
grep NOTICE absent.log | wc -l
status=$?
echo "Count ended"
exit "$status"
  1. 0
  2. 1
  3. 2
  4. 127
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

O que é impresso por este script?

set -e
false || echo "Handled"
echo "Next"
  1. Apenas Handled.
  2. Apenas Next.
  3. Handled, depois Next.
  4. Nada é impresso.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Em um bloco case, por que *) deve vir depois dos padrões de ações nomeadas?
  1. Ele corresponde a qualquer valor e ocultaria os ramos seguintes.
  2. Ele não corresponde a nenhum valor até um padrão nomeado falhar.
  3. Ele repete o ramo anterior para valores sem correspondência.
  4. Ele se aplica apenas a nomes de arquivo no diretório atual.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O diretório atual contém apenas os arquivos comuns draft one.jpeg, final.jpeg e notes.txt. Qual é a saída?

count=0
for f in *.jpeg; do
  [ "$f" = final.jpeg ] && continue
  echo "${f%.jpeg}.jpg"
  count=$(( count + 1 ))
done
echo "$count"
  1. draft.jpg, depois one.jpg, depois 2.
  2. draft one.jpg, depois final.jpg, depois 2.
  3. draft one.jpeg.jpg, depois 1.
  4. draft one.jpg, depois 1.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Um script executa until [ -f /tmp/upload.ready ]; do sleep 3; done. O arquivo comum já existe antes de o laço começar. Quantas vezes o corpo é executado?
  1. Exatamente uma vez.
  2. Zero vezes.
  3. Indefinidamente.
  4. Até ser removido.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um script de processamento em lote começa com status=0. Uma entrada inválida define status=1, e uma entrada posterior é processada com sucesso. Qual término informa que a solicitação ficou incompleta?
  1. Definir status=0 após o sucesso e usar exit "$status".
  2. Manter status=1 e terminar com um echo bem-sucedido.
  3. Definir status=0 e imprimir um erro na saída padrão.
  4. Manter status=1 e usar exit "$status".
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Novos arquivos de temporizador e serviço do sistema foram escritos. Qual comando faz o systemd reler suas definições antes de o temporizador ser habilitado?
  1. sudo systemctl daemon-reload
  2. sudo systemctl start report.service
  3. sudo systemctl list-timers
  4. sudo journalctl -u report.service
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 4: Diagnosticar entradas, fluxo de execução e períodos desligados10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Um arquivo de script é renomeado de weekly.sh para weekly, sem alterar seu conteúdo ou suas permissões. O que a perda da extensão faz com a escolha do interpretador pelo Linux com base no shebang?
  1. Faz o Linux escolher o shell de login atual.
  2. Faz o Linux escolher /bin/sh por padrão.
  3. Deixa a escolha do interpretador inalterada.
  4. Impede o Linux de ler o shebang.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um Bash pai executa export REGION=north e depois inicia um script que atribui REGION=south e termina. Qual valor permanece no processo pai?
  1. north
  2. south
  3. Um valor vazio.
  4. A variável deixa de estar definida.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Em um diretório sem outros arquivos, um script define pattern="*.txt". Qual argumento touch "$pattern" recebe?
  1. Nenhum caminho, pois nada corresponde.
  2. Um caminho para cada arquivo de texto existente.
  3. O caminho literal "*.txt" com as aspas.
  4. O caminho literal *.txt.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

O que acontece neste script não interativo?

set -eu
dest=
if [ -z "$dest" ]; then
  dest=${2:-/srv/archive}
fi
echo "$dest"

O script recebe apenas um argumento, input.txt.

  1. Ele para porque dest recebeu texto vazio.
  2. Ele imprime /srv/archive e é bem-sucedido.
  3. Ele para porque o segundo argumento está ausente.
  4. Ele imprime input.txt e é bem-sucedido.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

A variável count contém 10, e o diretório atual permite gravação e não tem arquivo chamado 4. O que acontece?

if [ "$count" > 4 ]; then
  echo "High"
else
  echo "Low"
fi
  1. Ele não cria arquivo e imprime High.
  2. Ele cria 4 e imprime Low.
  3. Ele não cria arquivo e imprime Low.
  4. Ele cria 4 e imprime High.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Um script faz a correspondência case "$value" in [0-9]*) echo "Match" ;; *) echo "No" ;; esac. O que acontece para value=8draft?
  1. Ele imprime Match.
  2. Ele imprime No.
  3. Ele falha porque o valor contém letras.
  4. Ele imprime tanto Match quanto No.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O que é impresso?

i=0
total=0
while [ "$i" -lt 4 ]; do
  i=$(( i + 1 ))
  [ "$i" -eq 2 ] && continue
  total=$(( total + i ))
  [ "$total" -gt 5 ] && break
done
echo "$i:$total"
  1. 4:10
  2. 3:4
  3. 4:8
  4. 2:1
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Um script recebe -v, uma string vazia entre aspas e "red room", nessa ordem. Ele executa shift e depois for arg in "$@"; do echo "<$arg>"; done. O que é impresso?
  1. <red>, depois <room>.
  2. <>, depois <red room>.
  3. Apenas <red room>.
  4. <-v>, depois <>, depois <red room>.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Quais datas 0 11 9 * 2 /home/rae/bin/check.sh seleciona no cron comum?
  1. Apenas terças-feiras que sejam dia 9, às 11:00.
  2. Toda terça-feira e todo dia 9, às 11:00.
  3. Toda terça-feira de setembro, às 11:00.
  4. Apenas a segunda terça-feira, às 11:09.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um temporizador de calendário habilitado tem Persistent=true. Três ativações diárias passam enquanto o computador está desligado. Qual recuperação ele providencia quando é reativado?
  1. Uma ativação do serviço para o trabalho de calendário perdido.
  2. Três ativações, uma para cada execução diária perdida.
  3. Nenhuma ativação até a próxima correspondência futura do calendário.
  4. Ativações contínuas até a máquina ser desligada.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 5: Combinar proteção com aspas, verificações de falha e entradas reutilizáveis10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Um terminal Bash está em /home/rae, com PATH /home/rae/bin:/usr/local/bin:/usr/bin:/bin. Scripts Bash executáveis chamados scan existem nas duas pastas bin e no diretório atual. Cada um contém apenas um shebang Bash e cd /srv/cache; esse diretório existe e é acessível. Qual arquivo o primeiro comando executa e quais caminhos são impressos?

scan
pwd
source ./scan
pwd
  1. /usr/local/bin/scan; depois /home/rae e /srv/cache.
  2. /home/rae/bin/scan; depois /home/rae e /srv/cache.
  3. ./scan; depois /srv/cache e /srv/cache.
  4. /home/rae/bin/scan; depois /srv/cache e /srv/cache.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um diretório contém apenas a.txt e b.txt. Com as configurações padrão de separação e expansão de nomes de arquivo do Bash, quantos argumentos de dados são formatados por printf '<%s>\n' $value após value="*.txt spare"?
  1. Um: o literal *.txt spare.
  2. Dois: os literais *.txt e spare.
  3. Três: a.txt, b.txt, spare.
  4. Dois: a.txt spare e b.txt spare.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um comando imprime ready na saída padrão e warning na saída de erro padrão e depois é bem-sucedido. O que é armazenado por message=$(the_command)?
  1. Apenas ready.
  2. Apenas warning.
  3. Ambas as linhas em ordem.
  4. O código de saída 0 do comando.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Qual código de saída chega a quem chamou o script?

#!/bin/bash
false
saved=$?
true && echo "Handled"
exit $(( saved + 2 ))
  1. 0
  2. 1
  3. 2
  4. 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um script usa set -u e já atribuiu folder="". Ele deve parar com uma mensagem de diagnóstico útil antes de usar uma pasta ausente ou vazia. Qual expansão fornece essa verificação?
  1. ${folder:?Folder required}
  2. ${folder:-Folder required}
  3. "$folder"
  4. ${folder}
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Qual teste verifica se "$text" tem comprimento diferente de zero?
  1. [ -z "$text" ]
  2. [ -s "$text" ]
  3. [ -n "$text" ]
  4. [ -e "$text" ]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Para limit=3, quais valores são impressos por for i in {1..$limit}; do echo "$i"; done na expansão comum do Bash?
  1. Três valores: 1, 2, 3.
  2. Um valor: o literal {1..$limit}.
  3. Nenhum valor, pois a lista está vazia.
  4. Um valor: o literal {1..3}.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Qual contagem é impressa com o comportamento padrão de encadeamentos do Bash? O arquivo contém três linhas terminadas por caracteres de nova linha.

count=5
cat tasks.txt | while IFS= read -r line; do
  count=$(( count + 1 ))
done
count=$(( count + 2 ))
echo "$count"
  1. 10
  2. 7
  3. 8
  4. 5
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um script analisa suas entradas com este código e depois exige exatamente dois argumentos de arquivo. Após a chamada ./copy.sh -v -- "early notes.txt" -final.txt, quantos argumentos restam e o que deve acontecer em seguida?

while [ "$#" -gt 0 ]; do
  case "$1" in
    -v) verbose=1; shift ;;
    --) shift; break ;;
    -*) echo "Unknown option" >&2; exit 2 ;;
    *) break ;;
  esac
done
  1. Restam três; rejeitar o marcador adicional de fim de opções.
  2. Restam dois; rejeitar -final.txt como opção desconhecida.
  3. Restam dois; validar ambos os caminhos e tentar a cópia.
  4. Resta um; usar um valor padrão para o destino ausente.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um script agendado usa sintaxe Bash e é executável com um shebang Bash. Ele funciona no terminal, mas o cron informa que um comando auxiliar está ausente. O comando auxiliar existe em /home/rae/.local/bin. Qual alteração resolve a provável diferença?
  1. Alterar o shebang Bash do script para /bin/sh.
  2. Adicionar um campo de usuário ao crontab pessoal.
  3. Tornar executável novamente o script já executável.
  4. Usar o caminho absoluto do auxiliar ou definir o PATH do cron.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Travou em uma questão sua? Ajuda com Tarefas

Termos-Chave

76 Termos-Chave, cada um com sua definição

A

Ambiente mínimo
Um ambiente mínimo fornece apenas um pequeno conjunto de configurações de processo, sem as variáveis e os arquivos de inicialização de uma sessão interativa.
O ambiente mínimo do cron pode omitir um diretório bin pessoal que estava disponível no terminal.
Anacron
O Anacron executa tarefas periódicas perdidas durante um período desligado, geralmente tratando trabalhos diários, semanais e mensais após a inicialização.
O Anacron pode recuperar uma tarefa diária em um notebook que estava desligado em seu horário habitual.
Aspas duplas
As aspas duplas preservam espaços e caracteres curinga em um valor enquanto permitem expansões de variáveis, comandos e expressões aritméticas.
As aspas duplas em echo "Home: $HOME *" permitem a expansão do caminho pessoal enquanto mantêm o asterisco.
Aspas simples
As aspas simples delimitam texto literal, impedindo expansões de variáveis, comandos e caracteres curinga na parte entre aspas.
As aspas simples fazem echo '$HOME' imprimir os caracteres “$HOME” em vez de um caminho de diretório pessoal.
Atribuição
Uma atribuição armazena um valor sob um nome de variável usando name=value, sem espaços ao redor do sinal de igualdade.
A atribuição name="Lee Kim" mantém as duas palavras juntas como um valor armazenado.

B

Bash
O Bash é o Bourne Again Shell, um interpretador de comandos usado interativamente e para executar scripts em sistemas Linux.
Um script que usa [[ ... ]] seleciona o Bash em seu shebang para que sua sintaxe condicional seja entendida.
break
O comando break sai imediatamente do laço atual para que a execução continue após o comando de fechamento desse laço.
Um laço de menu usa break quando o usuário digita “q” e nenhuma outra escolha do menu deve ser lida.

C

case
Um bloco case compara um valor com padrões em ordem e executa os comandos pertencentes ao primeiro ramo correspondente.
Um bloco case pode tratar “start”, “stop” e um comando sem correspondência em ramos separados.
Código de saída
Um código de saída é um resultado inteiro de comando de 0 a 255; zero significa sucesso e outros valores informam resultados documentados.
O código de saída de grep -q distingue uma correspondência, nenhuma correspondência e um problema ao ler a entrada.
Código de saída do encadeamento
Um código de saída do encadeamento é o resultado de um encadeamento de comandos, normalmente obtido de seu comando final, a menos que pipefail altere essa regra.
O código de saída do encadeamento pode ser zero quando grep falha, mas o wc seguinte conta com sucesso uma entrada vazia.
Comentário
Um comentário é um texto explicativo ignorado pelo shell, introduzido por # no início de uma palavra fora de texto entre aspas.
O comentário # Keep a copy for recovery explica por que a cópia de arquivo seguinte é necessária.
Comparação de strings
Uma comparação de strings verifica o texto caractere por caractere, de modo que grafias diferentes ou zeros iniciais podem tornar os valores diferentes.
Uma comparação de strings trata “07” e “7” como diferentes, embora representem o mesmo número inteiro.
Comparação numérica
Uma comparação numérica avalia valores inteiros com operadores como -eq e -gt, independentemente do comprimento de seu texto.
A comparação numérica [ "$count" -ge 8 ] é bem-sucedida para uma contagem armazenada de 12.
Contador
Um contador é um número armazenado e atualizado à medida que eventos ou passagens de um laço ocorrem, geralmente adicionando um ao valor anterior.
Um contador inicializado com count=0 pode aumentar uma vez para cada linha que um laço lê.
continue
O comando continue pula os comandos restantes na passagem atual do laço e segue para a próxima passagem ou verificação de condição.
Um laço de arquivos usa continue após uma verificação malsucedida para que seu comando de processamento não receba um caminho ausente.
cron
O cron é um serviço de agendamento em segundo plano que inicia comandos quando seus campos de tempo no crontab correspondem ao horário atual.
Uma tarefa do cron pode executar um script de relatório executável às 06:15 em cada dia útil sem um terminal aberto.

D

Diário de registros do systemd
O diário de registros do systemd armazena a saída de serviços e registros de diagnóstico, permitindo inspecionar o trabalho agendado após sua execução.
A consulta ao diário de registros journalctl -u backup.service mostra mensagens da tarefa de cópia de segurança.
Divisão inteira
A divisão inteira calcula um quociente inteiro e descarta a parte fracionária em vez de produzir um resultado decimal.
A divisão inteira faz $(( 7 / 2 )) produzir 3, embora o quociente exato seja 3,5.

E

elif
A palavra-chave elif introduz outra condição em um bloco if, testada apenas quando todas as condições anteriores nesse bloco falharam.
Um teste elif para 75% de uso só é executado após a falha do teste anterior para pelo menos 90%.
errexit
errexit é a opção set -e do Bash, que encerra a execução em falhas não tratadas, permitindo contextos específicos que testam o código de saída de comandos.
A opção errexit permite que uma condição if malsucedida selecione seu ramo else em vez de encerrar o script.
Execução no shell atual
A execução no shell atual consiste em ler os comandos de um arquivo nesse shell para que suas atribuições e mudanças de diretório o afetem.
Executar ./settings.sh com source carrega suas atribuições de variáveis diretamente na sessão Bash aberta.
Execução por curto-circuito
A execução por curto-circuito usa o código de saída de um comando para decidir se o próximo comando em uma lista && ou || será executado.
A execução por curto-circuito em cd /data || exit 1 interrompe comandos dependentes após uma mudança de diretório malsucedida.
exit
O comando interno exit encerra o shell ou script e informa um código fornecido ou, quando nenhum número é informado, o código do comando anterior.
Um script usa exit 2 após um erro de uso para que quem o chamou receba um resultado de falha.
Expansão aritmética
A expansão aritmética avalia uma expressão inteira dentro de $(( ... )) e insere o valor calculado no comando.
A expansão aritmética transforma "$(( count + 1 ))" na próxima contagem inteira.
Expansão de chaves
A expansão de chaves cria uma lista fixa a partir de uma notação como {1..5} antes de o Bash realizar a expansão de variáveis no comando.
A expansão de chaves não pode transformar {1..$n} em um intervalo baseado no valor armazenado em n.
Expansão de nomes de arquivo
A expansão de nomes de arquivo substitui um padrão de nome de arquivo sem aspas por caminhos correspondentes; o Bash normalmente mantém um padrão sem correspondência como texto literal.
A expansão de nomes de arquivo expande *.log em nomes correspondentes separados antes de um laço for começar.
Expansão de variável
A expansão de variável substitui um nome precedido de cifrão por seu valor armazenado enquanto o Bash prepara um comando para execução.
A expansão de variável transforma "${file}_old" em “report_old” quando file contém “report”.
Exportação de variável
Uma exportação de variável marca uma variável do shell para inclusão no ambiente herdado pelos programas que esse shell inicia depois.
A exportação de BACKUP_DIR permite que um script de cópia de segurança recém-iniciado leia o destino configurado.

F

Fim de arquivo
O fim de arquivo é o ponto em que um fluxo de entrada não tem mais dados; read do Bash informa falha ao encontrar essa condição.
No fim do arquivo, um registro final sem caractere de nova linha pode ser armazenado mesmo que read informe falha.

I

IFS
IFS é a variável de separador interno de campos do shell; defini-la como vazia para read preserva espaços em branco no início e no fim.
Usar IFS= read -r line mantém os espaços nas extremidades de cada registro lido do arquivo de entrada.
Indicador de falha
Um indicador de falha é um valor armazenado que registra uma parte malsucedida de uma tarefa maior para que o código final permaneça diferente de zero.
Um indicador de falha permanece definido após um arquivo ausente, mesmo quando o script conta com sucesso um arquivo posterior.
Interpretador
Um interpretador é um programa que lê e executa instruções escritas em uma linguagem que ele entende.
O interpretador selecionado por #!/usr/bin/python3 lê código Python em vez de comandos Bash.
Iteração
Uma iteração é uma passagem pelo corpo de um laço, usando o item atual da lista ou os valores atuais antes do início da próxima passagem.
Uma iteração de um laço de arquivos processa o único nome “beach day.jpeg” antes de avançar.

L

Laço for
Um laço for repete comandos para cada item de uma lista, atribuindo esse item à variável do laço antes de executar o corpo.
Um laço for sobre web1 web2 db1 executa seu corpo uma vez para cada um dos três nomes de host.
Laço until
Um laço until testa um comando antes de cada passagem e repete seu corpo até que esse comando retorne sucesso.
Um laço until pode pausar entre verificações enquanto espera aparecer um arquivo que indique a conclusão de uma exportação.
Laço while
Um laço while testa um comando antes de cada passagem e repete seu corpo enquanto esse comando retorna sucesso.
Um laço while que lê um arquivo termina quando read chega ao fim do arquivo e informa falha.

M

Mensagem de uso
Uma mensagem de uso mostra como chamar um comando, nomeando argumentos obrigatórios e marcando entradas opcionais ou repetíveis.
A mensagem de uso “Usage: count.sh FILE...” indica que as entradas de arquivo podem ser repetidas.

N

Negação
A negação inverte o sucesso e a falha de um comando ou teste, permitindo que uma condição selecione casos em que a condição original é falsa.
A negação em [ ! -d "$p" ] aceita tanto um arquivo comum quanto um caminho que não existe.
nounset
nounset é a opção set -u do Bash, que trata a expansão de uma variável não definida como erro em um script não interativo.
Com nounset habilitado, um nome de variável digitado incorretamente pode interromper um script antes que ele use um caminho vazio.

O

Opção
Uma opção é uma entrada de linha de comando que altera o comportamento, geralmente escrita com um hífen inicial e consumida antes dos argumentos comuns.
A opção -v pode habilitar mensagens adicionais antes que o script processe os nomes de arquivo restantes.

P

Padrão que corresponde a qualquer valor
Um padrão que corresponde a qualquer valor corresponde a todos os valores restantes, geralmente * no final de um bloco case do Bash.
O padrão geral *) informa comandos desconhecidos após a verificação dos subcomandos nomeados.
Palavra-chave condicional
Uma palavra-chave condicional, como [[ do Bash, inicia uma estrutura de teste do shell com suas próprias regras de interpretação e correspondência de padrões.
A palavra-chave condicional [[ permite usar [[ $name == *.log ]] sem separar o nome em palavras.
Parâmetro posicional
Um parâmetro posicional armazena um argumento fornecido a um script, numerado a partir de $1, com chaves obrigatórias para posições após a nona.
O parâmetro posicional ${10} recupera o décimo argumento sem acrescentar um zero a $1.
Passo de agendamento do cron
Um passo de agendamento do cron seleciona valores regularmente espaçados dentro de um campo de tempo, recomeçando no intervalo desse campo em vez de medir o tempo decorrido.
Um passo do cron de */45 no campo de minutos seleciona 0 e 45 e depois recomeça em 0 na hora seguinte.
PATH
PATH é o valor de ambiente separado por dois-pontos que lista os diretórios pesquisados para nomes de comandos que não contêm barra.
O shell pesquisa o PATH para job.sh, mas segue o caminho explícito do diretório atual em ./job.sh.
Permanência do gerenciador de usuário sem sessão ativa
A permanência do gerenciador de usuário sem sessão ativa permite que o gerenciador do systemd de um usuário permaneça disponível sem uma sessão de login ativa para que serviços e temporizadores de usuário possam ser executados.
Um administrador habilita a permanência quando uma tarefa agendada de um usuário deve continuar sem login.
Permissão de execução
A permissão de execução permite que um usuário autorizado inicie um arquivo como programa, incluindo um script cujo shebang seleciona seu interpretador.
Adicionar permissão de execução com chmod u+x job.sh permite que o proprietário tente executar ./job.sh.
pipefail
pipefail é uma opção do Bash que faz um encadeamento retornar o código de saída do comando malsucedido mais à direita, ou zero quando todos os comandos são bem-sucedidos.
Com pipefail habilitado, uma entrada ausente informada por grep pode fazer todo o encadeamento falhar.
Processo filho
Um processo filho é um processo iniciado por outro processo, com seu próprio estado e valores de ambiente herdados.
Um script em um processo filho pode mudar de diretório sem mover o terminal que o iniciou.
Proteção de caracteres com aspas ou escape
A proteção de caracteres com aspas ou escape controla como o Bash interpreta caracteres especiais e mantém o texto pretendido junto enquanto prepara argumentos de comando.
Colocar "$file" entre aspas preserva “monthly report.txt” como um argumento ao copiar o arquivo.

Q

Quantidade de argumentos
A quantidade de argumentos é o número de argumentos posicionais fornecidos, disponível como $#, excluindo o nome usado na chamada.
A quantidade de argumentos é 2 para ./greet.sh Ana "Lee Kim" porque o nome entre aspas é um argumento.

R

Ramo condicional
Um ramo condicional é um grupo de comandos selecionado por uma condição ou correspondência de padrão, oferecendo ações diferentes para entradas diferentes.
Um ramo de uso de disco para o limite mais alto deve vir antes de um limite de aviso sobreposto.
Rastreamento de execução
O rastreamento de execução imprime comandos após a expansão enquanto o Bash os executa, tornando visíveis os valores usados para depuração.
O rastreamento com bash -x revela um argumento de origem vazio passado a um comando de cópia de arquivo.
read
O comando interno read do Bash recebe uma linha da entrada padrão e armazena seus campos nas variáveis nomeadas no comando.
Usar read -r -p "Name: " name solicita um nome e mantém as barras invertidas no texto digitado.
Remoção de sufixo
A remoção de sufixo é uma expansão de parâmetro que remove uma terminação correspondente do valor de uma variável, como em ${f%.jpeg}.
A remoção de sufixo transforma “lake.jpeg” em “lake”, de modo que um comando de renomeação pode então acrescentar “.jpg”.
Repasse de argumentos
O repasse de argumentos passa os valores recebidos por um script a outro comando, geralmente usando "$@" para preservar os limites de cada um.
O repasse de argumentos com "$@" mantém uma entrada vazia e um nome com várias palavras como argumentos separados.
Resto da divisão
O resto da divisão é a quantidade inteira que sobra após uma divisão inteira; a aritmética do Bash o obtém com o operador %.
O resto em $(( 17 % 5 )) é 2 porque três grupos completos de cinco usam 15.

S

Saída de erro padrão
A saída de erro padrão é o fluxo de saída para mensagens de diagnóstico, separado da saída padrão para que os dados normais possam ser redirecionados independentemente.
Uma mensagem enviada à saída de erro padrão com >&2 permanece visível quando a saída padrão vai para um arquivo.
Script de shell
Um script de shell é um arquivo de texto simples com comandos de shell, salvo para que um interpretador possa executá-los como uma tarefa repetível.
Um script de shell pode criar uma pasta de cópia de segurança, copiar anotações para ela e listar a cópia salva.
Separação de palavras
A separação de palavras divide uma expansão sem aspas em palavras separadas usando caracteres delimitadores, normalmente espaços, tabulações e caracteres de nova linha.
A separação de palavras transforma um valor “my report.txt” sem aspas em dois argumentos antes de cp ser executado.
Shebang
Um shebang é a primeira linha que começa com #! e indica o interpretador que o Linux deve usar para executar um script.
O shebang #!/bin/bash começa no primeiro caractere, antes de qualquer comentário ou linha em branco.
shift
O comando interno shift remove parâmetros posicionais iniciais e renumera os restantes, reduzindo a quantidade de argumentos.
Após shift consumir -v, a próxima palavra da linha de comando se torna $1 para o analisador de opções.
Substituição de comando
A substituição de comando executa um comando e insere sua saída padrão, removendo os caracteres de nova linha no final, por meio da forma $(command).
A substituição de comando em today=$(date +%F) captura uma data para uso no nome de um arquivo de cópia de segurança.

T

Tabela de agendamento do cron
Uma tabela de agendamento do cron é um conjunto de entradas do cron, com cinco campos de tempo e um comando em cada linha de tarefa de uma tabela pessoal.
O comando crontab -l exibe o crontab do usuário atual para que seus agendamentos possam ser inspecionados.
Temporizador de calendário
Um temporizador de calendário corresponde a datas e horários por meio de OnCalendar e pode recuperar trabalho perdido quando Persistent é verdadeiro.
Um temporizador de calendário que usa OnCalendar=Mon..Fri 09:00 seleciona as manhãs dos dias úteis às 09:00.
Temporizador monotônico
Um temporizador monotônico mede o tempo decorrido a partir de um evento, como a inicialização ou a última ativação do serviço, em vez de corresponder a um horário de calendário.
Um temporizador monotônico pode combinar OnBootSec e OnUnitActiveSec para uma primeira execução e intervalos posteriores.
Terminador de linha
Um terminador de linha marca o fim de uma linha de texto; o Unix usa um caractere de nova linha, enquanto o Windows normalmente adiciona um retorno de carro antes dele.
Um terminador de linha do Windows em um shebang pode fazer o Linux procurar um caminho de interpretador terminado em ^M.
Teste de arquivo
Um teste de arquivo verifica a existência, o tipo ou as propriedades de acesso de um caminho e retorna um código de saída que uma condição pode usar.
O teste de arquivo [ -d "$src" ] aceita um diretório de origem, mas rejeita um arquivo comum.
Tratamento de sinais e eventos
Um tratamento de sinais e eventos registra um comando para ser executado quando um sinal ou evento selecionado do shell ocorre, como EXIT quando o processo Bash termina.
Um trap em EXIT pode remover o arquivo temporário cujo caminho foi armazenado anteriormente no script.

U

Unidade de serviço
Uma unidade de serviço define o trabalho que o systemd deve iniciar, como um script de execução única especificado por um caminho absoluto em ExecStart.
A unidade de serviço backup.service define o script ativado pelo temporizador de cópia de segurança correspondente.
Unidade de temporizador
Uma unidade de temporizador fornece um agendamento do systemd que ativa outra unidade, normalmente o serviço com o mesmo nome-base.
Habilitar a unidade de temporizador backup.timer estabelece o agendamento do serviço de cópia de segurança.

V

Validação
A validação verifica se a entrada atende aos requisitos de um script antes do início do trabalho dependente, incluindo quantidades e tipos de argumentos.
A validação rejeita um diretório quando um script de contagem exige um arquivo comum como entrada.
Valor padrão
Um valor padrão fornece uma entrada opcional quando nenhum valor utilizável foi informado, como ${1:-/var/log} para um argumento ausente ou vazio.
Um valor padrão permite que um relatório agendado use um diretório habitual sem solicitar uma resposta a uma pessoa.
Variável
Uma variável é um valor nomeado armazenado pelo shell e expandido quando um comando precisa usar o valor associado a esse nome.
A variável city armazena “Lisbon” após city=Lisbon, portanto echo "$city" pode exibi-lo.
Variável de ambiente
Uma variável de ambiente é um valor nomeado incluído no ambiente copiado de um processo para os programas que ele inicia.
A variável de ambiente HOME fornece um caminho de diretório pessoal a muitos comandos iniciados por um shell.
Verificação de sintaxe
Uma verificação de sintaxe lê um script para encontrar estruturas de shell malformadas sem executar os comandos nem testar seus resultados reais.
Uma verificação de sintaxe com bash -n detecta um done ausente antes que o laço possa executar comandos.

Sobre esta aula

Por StudeliRelatar um erro

Crie seus próprios Materiais de Estudo

Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.

Começar