Olá pessoal. Esta é uma tradução do RedHat RHCE Exam Preparation Book. Na minha opinião, é muito acessível sobre o básico do bash.
Os scripts de shell são uma ciência em si. Sem entrar em detalhes de tudo o que acontece "oculto", você aprenderá como usar os elementos básicos para escrever seus próprios scripts e analisar o que acontece nos scripts de shell de terceiros.

Compreendendo os elementos básicos dos scripts de shell
De fato, um shell script é uma lista de comandos executados seqüencialmente, além de alguma lógica que permite que o código seja executado apenas sob determinadas condições.
Para entender scripts shell complexos, é recomendável que você comece com scripts básicos.
O seguinte é um script muito simples:
Ele contém vários elementos que devem ser usados em todos os scripts. Para iniciantes, há shebang - esta é a linha #! / Bin / bash. Quando o script é iniciado a partir do shell pai, ele abre um subshell no qual os comandos especificados no script são executados.
Esses comandos podem ser interpretados de várias maneiras. Para entender exatamente como eles devem ser interpretados, o shebang é usado. No exemplo acima, shebang deixa claro que o script deve ser executado pelo shell bash.
Outras conchas também podem ser indicadas. Por exemplo, se seu script contiver código Perl, shebang deve ser #! / Usr / bin / perl. Iniciar um script com shebang é uma boa prática; se omitido, o código do script será executado pelo mesmo shell usado para executar o script.
Imediatamente após o shebang, há uma parte explicando sobre o que é o script. Algumas linhas de comentário no início de cada cenário são uma boa ideia. Em um script curto, muitas vezes é óbvio o que ele faz, mas, à medida que o script fica mais longo e à medida que mais pessoas se envolvem em escrevê-lo e apoiá-lo, fica menos claro o que os autores pretendem fazer.
Para evitar essa situação, adicione linhas de comentário começando com cada caractere #. Os comentários podem estar não apenas nas primeiras linhas, mas também no início de cada subseção do script. Isso certamente ajudará se você ler seu script em alguns meses!
Você também pode comentar não apenas em subseções, mas também em linhas individuais.
Independentemente da posição em que é usado, tudo, desde o caractere # até o final da linha, é um comentário.
Após o bloco de comentários, o corpo do script está localizado. No exemplo acima, esses são vários comandos que são executados seqüencialmente. O corpo do script de shell pode aumentar à medida que se desenvolve.
No final do script, incluí a instrução
exit 0 . A instrução exit informa ao shell pai se o script foi bem-sucedido. O estado de saída do último comando no script é o estado de saída do próprio script, a menos que a
saída 0 seja usada no final do script.
É útil saber que você pode trabalhar com
exit para informar ao shell pai como foram as coisas.
Introduzido no shell pai, o echo $? permite consultar o status de saída do último script em execução.
Após criar o script, verifique se ele pode ser executado. A maneira mais comum de fazer isso é aplicar um pouco de execução a ele. Portanto, se o nome do arquivo de script for hello, use o
comando chmod + x ./hello para torná-lo executável.
O script também pode ser executado como um argumento para o comando bash. Nesse caso, digite
bash ./hello para executar o script hello. Se o script for executado como um argumento para o comando bash, o arquivo de script não precisará ser executável.
De fato, você pode armazenar o script em qualquer lugar, mas se você quiser armazená-lo em um diretório que não esteja incluído na variável $ PATH, será necessário executá-lo com ./ na frente do nome do script.
Digite
./hello para executar o script ou coloque-o no diretório padrão incluído na variável $ PATH, por exemplo, / usr / local / bin.
Você também pode colocar o script no diretório / bin, após o qual basta digitar o nome do arquivo em qualquer lugar do sistema de arquivos e o script será executado.
ExemploUsando
vi / bin / datetime, crie um arquivo chamado datetime no diretório / bin. Cole este conteúdo no arquivo criado:
Depois de salvar o arquivo, digite
chmod + x / bin / datetime para dar permissão ao arquivo para executar. Por exemplo, mude para o diretório inicial usando o
comando cd ~ e digite simplesmente
datetime .
Vá, por exemplo, para o diretório inicial do cd ~ e insira datetime.
[root@localhost ~]
Usando variáveis e entradas
Os scripts bash são muito mais do que apenas uma lista de comandos executados sequencialmente. Uma das coisas boas sobre scripts é que eles podem trabalhar com variáveis e entradas para tornar o script flexível. Nesta seção, você aprenderá como trabalhar com eles.
Usando parâmetros posicionais
Ao executar o script, você pode usar os argumentos. Um argumento é tudo o que você coloca atrás de um comando de script. Argumentos podem ser usados para tornar o script mais flexível. Pegue o comando
useradd lisa . Neste exemplo, o comando é
useradd e seu argumento,
lisa , indica o que precisa ser feito.
Como resultado desse comando, um usuário chamado lisa deve ser criado.
No script, o primeiro argumento é
$ 1 , o segundo é
$ 2. A Listagem 1 mostra como os argumentos podem ser usados. Tente executar esse código especificando nomes de usuários como parâmetros.
Listagem 1
Parâmetros significam entrada de dados antes de executar o script. Nesse caso, especifiquei
lisa ,
lori e
bob como parâmetros após o argumento script name:
[root@server1 ~]
Se você tentou executar o código de amostra, poderá notar que seu conteúdo não é perfeito. Se você usar três argumentos ao executar o script da Lista 1, ele funcionará perfeitamente. Se você usar apenas dois argumentos, o terceiro será gerado sem o valor $ 3.
Se você usar quatro argumentos, o quarto valor (que será armazenado em US $ 4) nunca será exibido. Portanto, se você quiser usar argumentos, é melhor usar uma abordagem mais flexível.
Listagem 2
A Listagem 2 mostra dois novos elementos relacionados aos argumentos:- $ # É um contador que mostra quantos argumentos foram usados ao executar o script.
- $ @ É uma lista de todos os argumentos que foram usados ao executar o script.
Para listar os argumentos que foram usados ao executar esse script, o loop for é usado. Nos loops
for , as instruções são executadas desde que a condição seja verdadeira. Nesse cenário, a condição
para i em $ @ significa "para cada argumento". Cada vez que o script passa pelo loop, o valor da variável
$ @ é atribuído à variável
$ i .
Portanto, desde que haja argumentos, o corpo do script é executado.
O corpo do loop for sempre começa com
do e fecha
done , e os comandos a serem executados são listados entre essas duas palavras-chave. Portanto, o script de exemplo usará
eco para exibir o valor de cada argumento e parar quando não houver mais argumentos disponíveis.
Vamos tentar o script na Listagem 2 neste exemplo:- Digite vi argumento para criar o arquivo de argumento e copie o conteúdo do script na Listagem 2 para este arquivo.
- Salve o arquivo e torne-o executável.
- Execute o comando ./argument abc . Você verá que três linhas são exibidas.
- Execute o comando ./argument abcdef . Você verá que, além de abc, de f também será exibido.
Variáveis
Uma variável é um rótulo usado para indicar um local específico na memória que contém um valor específico. As variáveis podem ser definidas estaticamente usando NAME = value ou dinamicamente. Existem duas soluções para definir dinamicamente uma variável:
- Use a palavra-chave read em um script para solicitar dados do usuário que está executando o script.
- Use substituição de comando para usar o resultado do comando e atribuí-lo a uma variável. Por exemplo, a data do comando +% d-% m-% y mostra a data atual no formato dia-mês-ano. Para fazer isso em um script, você pode usar HOJE = $ (data +% d-% m-% y) . Para substituir comandos, basta colocar o comando cujo resultado você deseja usar entre os colchetes.
Na seção anterior sobre parâmetros posicionais, você aprendeu como atribuir argumentos a variáveis ao executar um script. Em alguns casos, pode ser mais eficiente solicitar informações quando você achar que algo substancial está faltando. O script abaixo mostra como fazer isso.
Listagem 3. Script de amostra usando o comando
read
No script da Listagem 3, o operador
if ... then ... else ... fi é usado para testar a existência do argumento
$ 1 . Isso é feito usando
test (test é um comando separado). O comando test pode ser escrito de duas maneiras *:
test ou
[...] . No exemplo, a linha
se [-z $ 1] ... é executada para ver o teste (marque)
-z $ 1 .
*
- na verdade, três fontes (aprox. Tradutor)O teste -z verifica se
$ 1 existe ou não. Em outras palavras, a linha
se [-z $ 1] verifica se
$ 1 está vazio, o que significa que nenhum argumento foi fornecido quando esse script foi executado. Nesse caso, os comandos após a instrução
then são executados.
Observe que, ao escrever o comando de
teste com colchetes, é importante usar espaços após o colchete de abertura e antes do colchete de fechamento, sem espaços, o comando não funcionará.
Observe que a instrução
then segue imediatamente o
teste . Isso é possível porque um ponto-e-vírgula (;) é usado. O ponto e vírgula é um separador de comandos e pode substituir uma nova linha em um script.
A instrução
then executa dois comandos: o comando
echo , que exibe a mensagem na tela, e o comando
read .
O comando
read para o script para que a entrada do usuário possa ser processada e armazenada na variável TEXT. Portanto,
ler TEXT coloca toda a entrada do usuário na variável TEXT, que será usada posteriormente no script.
A próxima parte é representada pela
instrução else . Os comandos após a
instrução else são executados em todos os outros casos, o que nesse caso significa "caso contrário, se o argumento foi fornecido". Nesse caso, a variável TEXT é determinada e o valor atual de
$ 1 é atribuído a ela.
Observe como a variável é definida: imediatamente após o nome da variável, existe um sinal = seguido de $ 1. Observe que você nunca deve usar espaços ao definir variáveis.
Então, as condições if são fechadas usando o operador
fi . Após a conclusão da condição if, você tem certeza de que a variável TEXT está definida e possui um valor. A penúltima linha do script lê o valor da variável TEXT e mapeia esse valor para STDOUT usando o comando
echo . Observe que, para solicitar o valor atual de uma variável, ele se refere ao nome da variável, começando com o sinal $ à frente.
Você pode praticar usando este exemplo ao trabalhar com entrada.- Abra o editor e crie um arquivo chamado texto. Digite o conteúdo do código na Listagem 3 neste arquivo.
- Escreva o arquivo no disco e execute chmod + x text para torná-lo executável.
- Execute o script executando ./text e sem argumentos adicionais. Você verá que ele pede entrada.
- Execute o script usando " hello " como argumento (./text hello). O resultado exibirá "você inseriu o texto hello" em STDOUT.
Usando condições e loops
Como você já viu, instruções condicionais podem ser usadas em um script. Essas instruções condicionais são executadas apenas se uma determinada condição for atendida.
Existem várias instruções e loops condicionais no bash que são frequentemente usados.
- if ... then ... else - usado para executar código se uma determinada condição for atendida
- for - usado para executar comandos para um intervalo de valores
- while - usado para executar código se uma determinada condição for atendida
- before - usado para executar o código até que uma determinada condição seja atendida
- case - usado para avaliar um número limitado de valores específicos
se então mais
A
construção if then else é comum para avaliar condições específicas. Você já viu um exemplo com ele. Essa declaração condicional é frequentemente usada com o comando
test . Este comando permite verificar muitas coisas: por exemplo, não apenas se um arquivo existe, mas também comparar arquivos, comparar números inteiros e muito mais.
Você pode aprender mais sobre teste na referência com o comando man test.
O básico
se construir é
se ... então ... fi .
Ele compara uma condição, conforme mostrado no exemplo a seguir:
if [ -z $1 ] then echo no value provided fi
Na Listagem 3, você viu como pode avaliar duas condições, incluindo
outras em uma expressão. A Listagem 4 mostra como avaliar várias condições de
se para
outro . Isso é útil se você precisar verificar muitos valores diferentes.
Observe que este exemplo também usa vários comandos de
teste .
Listagem 4 . Exemplo com
if then else
|| e &&
Em vez de escrever
instruções completas
if ..., você pode usar os operadores lógicos
|| bem como
&& .
|| é um "OR" lógico e executará a segunda parte da instrução somente se a primeira parte não for verdadeira;
&& é um "AND" lógico e executará a segunda parte da declaração somente se a primeira parte for verdadeira.
Considere estas duas linhas: [ -z $1 ] && echo no argument provided
ping -c 1 8.8.8.8 2>/dev/null || echo node is not available
O primeiro exemplo verifica se
$ 1 está vazio. Se esta verificação estiver correta (o que basicamente significa que o comando termina com o código de saída 0), o segundo comando é executado.
No segundo exemplo, o comando
ping é usado para verificar a disponibilidade do host.
Este exemplo usa um "OR" lógico para exibir o texto "o nó não está disponível" no caso de uma falha no comando
ping .
Você encontrará isso frequentemente, em vez da
instrução if condicional,
&& e
|| . No exercício abaixo, você pode praticar o uso de instruções condicionais usando
if ... then ... else , ou
&& e
|| .
Exercício . Usando
if ... then ... elseNeste exercício, você trabalhará em um script que verifica o que é um arquivo e o que é um diretório.
- Inicie o editor e crie um script chamado filechk.
- Copie o conteúdo da Listagem 4 neste script.
- Execute alguns testes com ele, como ./filechk / etc / hosts , ./filechck / usr , ./filechk arquivo não existente .
For loop
O loop for é uma ótima solução para o processamento de intervalos de dados. Na Listagem 5, você pode ver o primeiro exemplo com
for , onde o intervalo é determinado e processado enquanto houver valores brutos nesse intervalo.
Listagem 5
Um loop
for sempre começa com a palavra-chave for, seguida por uma condição que precisa ser verificada. Isso é seguido pela palavra-chave do, seguida pelos comandos que devem ser executados; se a condição for verdadeira, o loop será finalizado usando a palavra
- chave
done .
No exemplo da Listagem 5, é possível ver que a condição é um intervalo de números entre parênteses designados à variável COUNTER.
Uma pequena explicaçãoAs expressões aritméticas internas
((...)) são calculadas e seu resultado é retornado. Por exemplo, no caso mais simples, a construção a = $ ((5 + 3)) atribuirá à variável "a" o valor da expressão "5 + 3" ou 8. Além disso, parênteses duplos permitem trabalhar com variáveis no estilo da linguagem C.
Primeiro, a variável é inicializada para 100 e, desde que o valor seja maior que 1, é subtraído 1. A cada iteração, desde que a condição seja verdadeira, o valor da variável $ COUNTER é exibido usando o comando
echo .
Na Listagem 6, você pode ver uma das minhas frases favoritas com
for . O intervalo é definido desta vez como uma sequência de números, começando de 100 e chegando a 104.
Listagem 6 for i in {100..104}; do ping –c 1 192.168.4.$i >/dev/null && echo 192.168.4.$i is up; done
Observe como o intervalo é determinado: primeiro você especifica o primeiro número, depois dois pontos e indica o último número no intervalo. Além disso, com
for i in, para cada um desses números, a variável
i é atribuída. Cada um desses números é atribuído à variável
ie o comando
ping é executado, em que a opção
-c 1 garante que apenas uma solicitação seja enviada.
O resultado do comando
ping não
é levado em consideração, portanto sua saída é redirecionada para / dev / null. Com base no status de saída do comando
ping , uma parte da expressão
&& é executada. Portanto, se o host estiver disponível, uma linha será exibida indicando que está em execução.
Entendendo enquanto e até
Se a instrução for que você acabou de ler for útil para trabalhar com intervalos de elementos, a instrução while será útil quando você desejar rastrear algo como acessibilidade do processo. Há também uma instrução
até , que é executada desde que a condição sendo verificada seja falsa. Na Listagem 7, você pode ler como
while é usado para monitorar a atividade do processo.
Nota Eu não entendi o que esse script faz. No meu caso, o CentOS 7 é usado e, por padrão, não há monitor, embora o script diga explicitamente: uso: monitor <nome do processo>
Em algum lugar por meia hora, pesquisei no Google o programa de monitoramento do CetOS, mas não o encontrei. E geralmente não está claro qual monitor lateral está aqui se o ps aux for usado. De qualquer forma, não entendi o que esse script faz. Uma grande solicitação para ajudar a resolver esse problema é ajustar o texto e / ou script.
Listagem 7
O script na Listagem 7 consiste em duas partes. Primeiro, há um
loop while . Em segundo lugar, há tudo o que precisa ser feito quando o
loop while não
é mais avaliado como verdadeiro.
O núcleo do
loop while é o comando
ps , que tem um valor de
$ 1 .
Observe o uso de
grep -v grep , que exclui as linhas que contêm o
comando grep do resultado. Lembre-se de que o comando
ps incluirá todos os processos em execução, incluindo o
comando grep , para os quais a saída do
comando ps é passada. Isso pode levar a uma correspondência positiva falsa.
A saída do comando
ps aux é redirecionada para / dev / tty11. Isso permite que você leia os resultados de tty11 posteriormente, se necessário, mas eles não são exibidos por padrão.
while , , .
sleep 5 , 5 .
while , . ( , ), , .
, .
mail -s “process $1 has stopped” root < . root , Linux*.
mail ,
-s .
* — CentOS . (. )< . .
mail , . , , . STDIN. - .
while —
until , 8.
until , , .
8
users $1 , . , . , ,
until .
8
case
—
case *.
case . ,
case Linux, .
* — ?case , , , .
9
case , .
9 case "$1" in start) start;; stop) rm -f $lockfile stop;; restart) restart;; reload) reload;; status) status ;; *) echo "Usage: $0 (start|stop|restart|reload|status)" ;; esac
O gabinete possui vários recursos. Primeiro vem a linha - caso em sequência . Isto é seguido por uma lista de todos os valores possíveis que precisam ser avaliados. Cada elemento é fechado com um colchete ) .Isto é seguido por uma lista de comandos a serem executados se um argumento específico foi usado. A lista de comandos é fechada com ponto e vírgula duplo ;; pode ser usado imediatamente após o último comando e pode ser usado em uma linha separada.Observe também que *) se aplica a todos os outros parâmetros não especificados anteriormente. Este é um operador abrangente.O loop de iteração do caso termina com a instrução esac .Observe que as seqüências no caso são executadas em ordem. Quando a primeira correspondência é feita, a declaração do caso não avalia nada.Como parte da avaliação, modelos semelhantes ao modelo podem ser usados. Isso é mostrado em *) uma sequência que corresponde a tudo. Mas você também pode usar sequências como start | Start | START) para combinar com outro caso .Depurando scripts no Bash
, , . ,
bash -x . , , , .
10
bash -x , ,
grep , , .
[root@server1 ~]
, . , .