Bash Loops com exemplos
- 2448
- 767
- Enrique Gutkowski PhD
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
eaté
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
Exemplos de loops de bash
- Vamos começar com um básico
para
laço:
cópia de$ para i em $ (seq 1 5); eco $ i; feito 1 2 3 4 5
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 doem
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:
cópia de$ seq 1 5 1 2 3 4 5
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:
cópia de$ Teste CAT.txt 1 2 $ echo "$ (teste de gato.txt | cabeça -n1) "1
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:
cópia de$ se ["a" == "a"]; Então eco!"; fi sim!
Observe como novamente o
;
está antes doentã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
ouse
precisa ser encerrado antes da próxima ação que é 'então' no exemplo de declaração if efazer
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 noeu
variável ($ i
)
;: Encerrar a declaração do eco (rescindir cada ação)
feito: Indique que este é o fim do nosso loop - Vamos dar o mesmo exemplo, mas escrevê -lo de maneira diferente:
cópia de$ para i em 1 2 3 4 5; eco $ i; feito 1 2 3 4 5
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.
- Aumentar a complexidade do nosso loop para incluir arquivos:
cópia de$ 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
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 noeu
variável, um arquivo por/para cada loop opara
Loop vai passar.Em outras palavras, a primeira vez que o loop (a parte entre fazer e fazer) acontece,
$ i
irá conter1.TXT
. A próxima corrida$ i
irá conter2.TXT
e assim por diante.Cat "$ i" | Cabeça -n1: Aqui pegamos o
$ i
variável (como vimos isso será1.TXT
, seguido pela2.TXT
etc.) e gato esse arquivo (exiba) e pegue a primeira linha do mesmoCabeça -n1
. Assim, 5 vezes1
é a saída, pois essa é a primeira linha em todos os 5 arquivos como podemos ver no anteriorCabeça -n1
através de tudo .arquivos txt. - Que tal um muito complexo agora?
cópia de$ 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 !
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 noem
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 fazerArquivo de cauda -N1.TXT
- Uma abreviação que novos desenvolvedores de bash podem perder facilmente. Em outras palavras, aqui é uma impressão simplesmente1
(A última linha em 1.txt) imediatamente seguido por2
para2.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:
cópia de$ para i em $ (ls *.txt 2>/dev/null); eco -n "$ (cauda -n1 $ i)"; feito 12345 $
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 oa partir de 1.TXT !
saída) e o fechamento do loop pelofeito
.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?
- Usando um loop de tempo para gerar uma string aleatória:
cópia de$ 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
Isso parece complexo! Vamos analisá -lo passo a passo. Mas primeiro, vamos ver como isso ficaria dentro de um script bash.
- Exemplo da mesma funcionalidade, implementada dentro de um script bash:
cópia de$ 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 "
$ 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 pordata +%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 oCONTAR
variável para0
Myrandom = na linha 7: defina oMyrandom
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 nossoCONTAR
variável por1
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. quandoCONTAR
é maior então10
o loop vai acabar)
Myrandom = "… na linha 14: vamos atribuir um novo valor aMyrandom
$ 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, ecoarALEATÓ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 loops10
tempos como resultado doCONTAR
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 oALEATÓRIO
variável retorna uma variável semi-aleatom (com base naAleató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ão1
etc. Como o primeiro personagem da saída é sempre tomado pelo sed! - 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 doenquanto
também na próxima linha, para que se torne desnecessário até usar o;
lá.
cópia de$ CAT Test2.sh #!/Bin/Bash for i em $ (seq 1 3) do eco "… looping… $ i…
$ ./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.
- Finalmente, vamos dar uma olhada em uma festa 'até' loop:
cópia de$ Nr = 0; até [$ nr -eq 5]; Echo "$ nr"; Nr = $ [$ nr + 1]; feito 0 1 2 3 4
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 nossose
condição, ou melhor nossoaté
doença. eu digose
Como a sintaxe (e o trabalho) é semelhante ao do comando de teste, eu.e. o comando subjacente que é usado emse
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ávelNr
atinge 5, então o teste se tornará verdadeiro, por sua vez, fazendo oaté
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ávelNr
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 loopComo 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.
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