Bash Loops com exemplos

Bash Loops com exemplos

Pronto para mergulhar no loop de batida? Com a popularidade do Linux como um sistema operacional gratuito e armado com o poder da interface da linha de comando Bash, pode -se ir ainda mais ainda, codificando loops avançados diretamente da linha de comando ou dentro de scripts bash.

Aproveitando esse poder, pode -se manipular qualquer documento, qualquer conjunto de arquivos ou implementar algoritmos avançados de quase qualquer tipo e sabor. É improvável que você encontre limitações se você usar o Bash como base para o seu script, e os loops de basquete formam uma parte poderosa disso.

Dito isto, os loops de bash às vezes podem ser complicados em termos de sintaxe e conhecimento circundante é fundamental. Hoje apresentamos a você um conjunto de exemplos de loop de bash para ajudá -lo a aumentar rapidamente e nos tornarmos proficientes! Vamos começar!

Neste tutorial, você aprenderá:

  • Como bash para, enquanto e até Loops baseados funcionam, com exemplos
  • Como o Bash requer o término de declarações de partida em loop antes da seção Do… Done do Loop pode seguir, e como isso se relaciona com se e outras declarações
  • Como implementar loops de bash básicos e médios avançados
  • Como funcionam as subs -grandes e como elas podem ser usadas dentro das declarações de escopo do Bash Loop
  • Como começar a codificar loops defensivamente, evitando erros na saída
  • Como codificar uma frase (um termo comum usado entre os desenvolvedores de bash) na linha de comando versus implementar o mesmo código em um script bash
  • Como ; O idioma da sintaxe é uma questão importante quando se trata de codificar loops de bash, tanto na linha de comando quanto nos scripts
Bash Script - Bash Loops com exemplos

Exemplos de loops de bash

  1. Vamos começar com um básico para laço:
    $ para i em $ (seq 1 5); eco $ i; feito 1 2 3 4 5
    cópia de

    Como você pode ver, básico para Loops in Bash são relativamente simples de implementar. Aqui estão as etapas:

    para: Indica que queremos iniciar um novo loop baseado
    eu: uma variável que usaremos para armazenar o valor gerado pela cláusula dentro do em palavra -chave (a saber, a sequência logo abaixo)
    $ (seq 1 5): Isso está executando um comando dentro de outra sub-concha.

    Para entender como isso funciona, considere este exemplo:

    $ seq 1 5 1 2 3 4 5
    cópia de

    Basicamente, o $ () A sintaxe pode ser usada sempre que (e onde quer que!) você quer começar uma nova subshell. Este é um dos recursos mais poderosos do shell da festa. Considere por exemplo:

    $ Teste CAT.txt 1 2 $ echo "$ (teste de gato.txt | cabeça -n1) "1
    cópia de

    Como você pode ver, aqui o subshell executou o teste de gato.txt | Head -n1 '(' Head -n1 'seleciona apenas a primeira linha) e depois ecoou a saída dessa subshell.

    Vamos continuar analisando o nosso loop acima:

    ;: Isto é muito importante. Em Bash, qualquer "ação", como por exemplo a 'para' em loop inicial, ou um teste de declaração 'se', ou um loop de tempo etc. precisa ser encerrado com um ';'. Assim, o ';' está aqui * antes * fazer, não depois. Considere este exemplo muito semelhante:

    $ se ["a" == "a"]; Então eco!"; fi sim!
    cópia de

    Observe como novamente o ; está antes do então, Não após. Por favor, não deixe isso confundi. Lembre -se de que toda ação precisa ser encerrada antes de qualquer nova ação e, portanto, para ou se precisa ser encerrado antes da próxima ação que é 'então' no exemplo de declaração if e fazer no loop acima!

    Finalmente, temos:

    fazer: Indicando que para O que vem antes … fazer… O que vem a seguir. Observe novamente que esta palavra de ação está após o fechamento ; usado para fechar a declaração de abertura do loop.
    eco $ i: Aqui em que produzimos o valor armazenado no eu variável ($ i)
    ;: Encerrar a declaração do eco (rescindir cada ação)
    feito: Indique que este é o fim do nosso loop

  2. Vamos dar o mesmo exemplo, mas escrevê -lo de maneira diferente:
    $ para i em 1 2 3 4 5; eco $ i; feito 1 2 3 4 5
    cópia de

    Você pode ver agora como isso se relaciona com o exemplo acima; É o mesmo comentário, embora aqui não tenhamos usado uma subshell para gerar uma sequência de entrada para nós, nós especificamos manualmente por nós mesmos.

    Isso deixa sua cabeça correr sobre possíveis usos um pouco? Então, deve fazer algo legal com isso agora.

  3. Aumentar a complexidade do nosso loop para incluir arquivos:
    $ ls 1.txt 2.txt 3.txt 4.txt 5.TXT
    cópia de
    $ Head -n1 *.txt ==> 1.TXT <== 1 ==> 2.TXT <== 1 ==> 3.TXT <== 1 ==> 4.TXT <== 1 ==> 5.TXT <== 1 
    cópia de
    $ para i em $ (ls *.TXT); Faça gato "$ i" | cabeça -n1; feito 1 1 1 1 1
    cópia de

    Você pode descobrir o que está acontecendo aqui? Olhando para as novas partes disso para o loop, vemos:
    $ (ls *.TXT): Isso listará todos os arquivos txt no diretório atual e observará que o nome desses arquivos será armazenado no eu variável, um arquivo por/para cada loop o para Loop vai passar.

    Em outras palavras, a primeira vez que o loop (a parte entre fazer e fazer) acontece, $ i irá conter 1.TXT. A próxima corrida $ i irá conter 2.TXT e assim por diante.

    Cat "$ i" | Cabeça -n1: Aqui pegamos o $ i variável (como vimos isso será 1.TXT, seguido pela 2.TXT etc.) e gato esse arquivo (exiba) e pegue a primeira linha do mesmo Cabeça -n1. Assim, 5 vezes 1 é a saída, pois essa é a primeira linha em todos os 5 arquivos como podemos ver no anterior Cabeça -n1 através de tudo .arquivos txt.

  4. Que tal um muito complexo agora?
     $ cauda -n1 *.txt ==> 1.TXT <== 1 ==> 2.TXT <== 2 ==> 3.TXT <== 3 ==> 4.TXT <== 4 ==> 5.TXT <== 5 
    cópia de
    $ para i em $ (ls *.txt 2>/dev/null); eco -n "$ (cauda -n1 $ i)"; eco "de $ i !"; feito 1 de 1.TXT ! 2 de 2.TXT ! 3 de 3.TXT ! 4 de 4.TXT ! 5 de 5.TXT ! 
    cópia de

    Você pode treinar o que está acontecendo aqui?

    Vamos analisá-lo passo a passo.

    para eu em : Já sabemos disso; começar de novo para loop, atribua variável i ao que se segue no em cláusula
    $ (ls *.txt 2>/dev/null): O mesmo que o comando acima; Liste todos os arquivos TXT, mas desta vez com um pouco de proteção definitiva para que evite erros no lugar. Olhar:

    $ para i em $ (ls i.fazer.não.existir); Echo "apenas testando a inexistência de arquivos"; feito ls: não posso acessar 'eu.fazer.não.existir ': nenhum arquivo ou diretório 

    Não é muito profissional Saída! Por isso;

    $ para i em $ (ls i.fazer.não.existir 2>/dev/null); Echo "apenas testando a inexistência de arquivos"; feito 

    Nenhuma saída é gerada por esta declaração.

    Vamos continuar nossa análise:

    ; fazer: encerrar a declaração de partida para loop, comece a seção Do ... Concluído de nossa definição de loop
    echo -n "$ (cauda -n1 $ i)";: Em primeiro lugar, o -n apoia Não produza a nova linha que se arrasta no final da saída solicitada.

    Em seguida, estamos pegando a última linha de cada arquivo. Observe como otimizamos nosso código de cima? eu.e. em vez de fazer arquivo de gato.txt | Tail -n1 Pode -se simplesmente fazer Arquivo de cauda -N1.TXT - Uma abreviação que novos desenvolvedores de bash podem perder facilmente. Em outras palavras, aqui é uma impressão simplesmente 1 (A última linha em 1.txt) imediatamente seguido por 2 para 2.TXT etc.



    Como uma sidenote, se não especificássemos o comando de eco de acompanhamento, a saída teria sido simplesmente 12345 Sem novas linhas:

    $ para i em $ (ls *.txt 2>/dev/null); eco -n "$ (cauda -n1 $ i)"; feito 12345 $
    cópia de

    Observe como até a última nova linha não está presente, daí a saída antes do prompt $ retorna.

    Finalmente temos eco "de $ i !"; (nos mostrando o a partir de 1.TXT ! saída) e o fechamento do loop pelo feito.

    Eu confio que agora você pode ver como isso é poderoso e quanto controle alguém pode exercer sobre arquivos, documentar o conteúdo e mais!

    Vamos gerar uma string aleatória longa com um pouco de loop a seguir! Diversão?

  5. Usando um loop de tempo para gerar uma string aleatória:
    $ Aleatória = "$ (data +%s%n | corte -b14-19)" $ contagem = 0; Myrandom =; enquanto é verdade; count = $ [$ count + 1]; se [$ count -gt 10]; então quebre; fi; Myrandom = "$ myrandom $ (echo" $ aleatório "| sed 's |^\ (.\).*| \ 1 | ') "; feito; echo" $ myrandom "6421761311
    cópia de

    Isso parece complexo! Vamos analisá -lo passo a passo. Mas primeiro, vamos ver como isso ficaria dentro de um script bash.

  6. Exemplo da mesma funcionalidade, implementada dentro de um script bash:
    $ Teste CAT.sh #!/BIN/BASH Random = "$ (data +%S%N | Cut -B14-19)" contagem = 0 myrandom = while True; DO Count = $ [$ count + 1] se [$ count -gt 10]; Então quebre fi myrandom = "$ myrandom $ (echo" $ aleatória "| sed 's |^\ (.\).*| \ 1 | ') "feito echo" $ myrandom "
    cópia de
    $ chmod +x teste.sh $ ./teste.SH 1111211213 $ ./teste.SH 1212213213 

    Às vezes, é surpreendente que esse código de loop de bash complexo pode ser tão facilmente movido para uma 'liner' (um termo que os desenvolvedores bash usam para se referir ao que é realidade um pequeno script, mas implementado diretamente da linha de comando, geralmente em um linhas únicas (ou no máximo algumas).



    Vamos agora começar a analisar nossos dois últimos exemplos - que são muito semelhantes. As pequenas diferenças de código, especialmente em torno do idioma ';' são explicados em Exemplo 7 abaixo:

    Random = "$ (Data +%S%N | Cut -B14-19)" na linha 4: isso leva (usando corte -b14-19) os últimos 6 dígitos do horário atual da época (o número de segundos que passaram desde 1 de janeiro de 1970), conforme relatado por data +%s%n e atribui essa string gerada à variável aleatória, definindo assim uma entropia semi-aleatória para o pool aleatório, em termos simples "tornando o pool aleatório um pouco mais aleatório".
    Contagem = 0 na linha 6: defina o CONTAR variável para 0
    Myrandom = na linha 7: defina o Myrandom variável para 'vazio' (nenhum valor atribuído)
    enquanto ... faça ... feito Entre a linha 9 e a linha 15: isso deve estar claro agora; Comece um loop de tempo, execute o código entre as cláusulas do Do ... feito.
    verdadeiro: e enquanto a declaração que se seguir o 'while' for avaliada como verdadeira, o loop continuará. Aqui a afirmação é 'verdadeira', o que significa que este é um loop indefinido, até quebrar declaração é dada.
    Count = $ [$ count + 1] na linha 10: Aumente nosso CONTAR variável por 1
    se [$ count -gt 10]; então na linha 11: uma declaração if para verificar se nossa variável é maior então -GT 10, E se assim for, execute o então… fi papel
    quebrar na linha 12: isso quebrará o indefinido enquanto o loop (i.e. quando CONTAR é maior então 10 o loop vai acabar)
    Myrandom = "… na linha 14: vamos atribuir um novo valor a Myrandom
    $ Myrandom Na linha 14: primeiro, pegue o que já temos dentro dessa variável; em outras palavras, estaremos anexando algo no final do que já está lá, e isso para cada loop subsequente
    $ (echo "$ aleatório" | sed 's |^\ (.\).*| \ 1 | ') na linha 14: esta é a parte que é adicionada a cada vez. Basicamente, ecoar ALEATÓRIO variável e leva o primeiro caractere dessa saída usando uma expressão regular complexa em sed. Você pode ignorar essa parte, se quiser, basicamente afirma: "Pegue o primeiro personagem do $ Aleatório saída variável e descarte todo o resto "

    Você pode ver como a saída (por exemplo 1111211213) é gerado; Um personagem (da esquerda para a direita) na época, usando o loop while, que loops 10 tempos como resultado do CONTAR Contra -variável verificação.

    Então, por que a saída é frequentemente no formato de 1,2,3 e menos de outros números? Isso é porque o ALEATÓRIO variável retorna uma variável semi-aleatom (com base na Aleatório =… semente) que está na faixa de 0 a 32767. Assim, muitas vezes esse número começa com 1, 2 ou 3. Por exemplo, 10000-19999, todos retornarão 1 etc. Como o primeiro personagem da saída é sempre tomado pelo sed!

  7. Um script curto para destacar a possibilidade de organizar o código de loop de bash de uma maneira diferente sem usar o ; idioma.

    Precisamos esclarecer as pequenas diferenças do script Bash versus o script de linha de comando de uma linha.

    OBSERVAÇÃO
    Observe que no script Bash (teste.sh) não há tantos ; expressões idiomáticas. Isso ocorre porque agora dividimos o código em várias linhas e um ; é não exigido quando houver um caractere EOL (final da linha) em vez disso. Esse personagem (Newline ou Return de carruagem) não é visível na maioria dos editores de texto, mas é auto -explicativo se você pensar no fato de que cada comando está em uma linha separada.

    Observe também que você pode colocar o fazer Cláusula do enquanto também na próxima linha, para que se torne desnecessário até usar o ; lá.

    $ CAT Test2.sh #!/Bin/Bash for i em $ (seq 1 3) do eco "… looping… $ i…
    cópia de
    $ ./test2.sh… looping… 1… loop… 2… loop… 3… 

    Pessoalmente, prefiro muito o estilo de sintaxe dado em Exemplo 6, Como parece mais claro qual é a intenção do código escrevendo a declaração de loop na íntegra em uma linha (semelhante a outros idiomas de codificação), embora as opiniões e os estilos de sintaxe sejam diferentes por desenvolvedor, ou por comunidade de desenvolvedores.

  8. Finalmente, vamos dar uma olhada em uma festa 'até' loop:
    $ Nr = 0; até [$ nr -eq 5]; Echo "$ nr"; Nr = $ [$ nr + 1]; feito 0 1 2 3 4
    cópia de

    Vamos analisar este exemplo:

    Nr = 0: Aqui defina uma variável nomeada Nr, a zero
    até: Começamos nosso loop 'até'
    [$ Nr -eq 5]: Este é o nosso se condição, ou melhor nosso até doença. eu digo se Como a sintaxe (e o trabalho) é semelhante ao do comando de teste, eu.e. o comando subjacente que é usado em se declarações. Em Bash, o comando de teste também pode ser representado por solteiro ["] Suportes. O $ Nr -eq 5 meios de teste; Quando nossa variável Nr atinge 5, então o teste se tornará verdadeiro, por sua vez, fazendo o até Fim do loop à medida que a condição é comparada (outra maneira de ler isso é 'até verdadeiro' ou 'até que nossa variável NR seja igual a 5'). Observe que uma vez que a NR é 5, o código do loop não é mais executado, portanto 4 é o último número exibido.
    ;: Encerrar nossa declaração até, conforme explicado acima
    fazer: Inicie nossa cadeia de ação a ser executada até que a declaração testada se torne verdadeira/válida
    eco "$ nr;": eco fora do valor atual de nossa variável Nr
    Nr = $ [$ nr + 1];: Aumente nossa variável por um. O $ ['…'] O método de cálculo é específico para a batida
    feito: Encerrar nossa cadeia de ação/código de loop

    Como você pode ver, enquanto e até que os loops sejam de natureza muito semelhante, embora na verdade sejam opostos. Enquanto os loops executam, desde que algo seja verdadeiro/válido, enquanto até que os loops executam desde que algo 'ainda não seja válido/verdadeiro'. Muitas vezes eles são intercambiáveis ​​revertendo a condição.

  9. Conclusão

    Eu acredito que você pode começar a ver o poder do Bash, e especialmente para, enquanto e até os loops de Bash. Só arranhamos a superfície aqui e posso voltar mais tarde com outros exemplos avançados. Enquanto isso, deixe-nos um comentário sobre como você está usando loops de bash em suas tarefas ou scripts diários. Aproveitar!

Tutoriais do Linux relacionados:

  • Loops aninhados em scripts de basquete
  • Mastering Bash Script Loops
  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Coisas para instalar no Ubuntu 20.04
  • Multi-thread Bash Script e Gerenciamento de Processos no…
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Sistema Linux Hung? Como escapar para a linha de comando e…
  • Manipulando a entrada do usuário em scripts bash
  • Mint 20: Melhor que o Ubuntu e o Microsoft Windows?
  • Coisas para instalar no Ubuntu 22.04