Como usar as sub -mais de bases dentro das declarações if if

Como usar as sub -mais de bases dentro das declarações if if

Se você já usou sub -explosões de bash ($ (…)), você sabe como as sub -mais flexíveis podem ser. Leva apenas alguns caracteres para iniciar uma subshell para processar qualquer coisa necessária, embutida para outra declaração. O número de casos de uso possíveis é praticamente ilimitado.

Também podemos usar subs -grandes bash dentro se declarações, alinhadas com a declaração. Fazer isso dá ao usuário e ao desenvolvedor muita flexibilidade adicional quando se trata de escrever Bash se declarações.

Se você ainda não estiver familiarizado (ou gostaria de saber mais sobre) Bash se declarações, consulte nossa festa se as declarações: se elif mais o artigo FI.

Neste tutorial, você aprenderá:

  • Como incorporar sub -explosões de basquete dentro se declarações
  • Métodos avançados para incorporar subsidiários Bash alinhados com outros comandos
  • Exemplos demonstrando o uso de sub -mais de bases em se declarações
Como usar as sub -mais de bases dentro das declarações if if

Requisitos de software e convenções usadas

Requisitos de software e convenções de linha de comando Linux
Categoria Requisitos, convenções ou versão de software usada
Sistema Independente da distribuição Linux
Programas Linha de comando Bash, sistema baseado em Linux
Outro Qualquer utilidade que não esteja incluída no shell bash por padrão pode ser instalada usando sudo apt-get install utility-name (ou yum install para sistemas baseados em redhat)
Convenções # - requer que o Linux -Commands seja executado com privilégios de raiz diretamente como usuário root ou por uso de sudo comando
$-exige que o Linux-Commands seja executado como um usuário não privilegiado regular

Exemplo 1: Iniciando simples

Vejamos um exemplo simples para começar. Observe que essas declarações, enquanto executadas aqui na linha de comando, também podem ser incorporadas a um script de shell bash (um arquivo de texto sem formatação, de preferência com um .sh extensão e marcada como executável usando o chmod +x myscript.sh Comando - onde MyScript.sh é um exemplo de nome de arquivo). Também apresentamos um erro para tornar as coisas mais interessantes.

$ se ["teste" == "$ (echo 'teste')"]; Então eco!'; else eco 'não corresponde!'; FI corresponde! $ se ["teste" == "$ (echo 'incorreto')"]; Então eco!'; outra 'não corresponde!'; Fi não corresponde!: comando não encontrado $ 


No primeiro comando, usamos um teste simples (se ["algum_text" == "algum_other_text"]; então… ) para verificar a igualdade entre duas cordas. Para a segunda sequência, iniciamos uma sub -Shell Bash ($ (…)) para produzir a palavra teste. O resultado é que teste partidas teste e assim os comandos após o então Cláusula será executada, neste caso eco 'correspondem!' é executado e Partidas! impressões.

No segundo comando, alteramos o comando echo para um texto incorreto corresponde, deixando o eco/saída da subshell incorreta ($ (echo 'incorreto')). Temos um erro de aparência estranha de volta. Olhe de perto, você pode identificar o erro? Compare também o segundo comando com o primeiro.

A questão é que, em nosso segundo comando, o outro Cláusula (que é executada quando a correspondência da igualdade falha, eu.e. 'o que outro fazer quando a declaração if não era verdadeira) perde um eco comando. Considerando que pode ler fluentemente (se ... então eco ... senão ...) o comando está incorreto, pois requer um eco adicional. O resultado é que o shell da partida tenta executar Não corresponde! Como um comando literal.

Vamos consertar isso!

$ se ["teste" == "$ (echo 'incorreto')"]; Então eco!'; else eco 'não corresponde!'; Fi não corresponde! 

Muito melhor. E podemos ver nossa subshell, é eco, e o completo se declaração executando corretamente. Ótimo, vamos mergulhar um pouco mais fundo.

Exemplo 2: Declaração um pouco mais complexa se baseada na subshell baseada

$ Var1 = "abc"; se [["$ (echo" $ var1 ")" == * "b" *]]; Então eco!'; else eco 'não corresponde!'; FI corresponde! $ Var1 = "adc"; se [["$ (echo" $ var1 ")" == * "b" *]]; Então eco!'; else eco 'não corresponde!'; Fi não corresponde! 

Aqui definimos uma variável Var para qualquer um abc ou ADC e a próxima saída desta variável, novamente usando uma subshell, contra a presença de b na string. Observe que o asterisco original (*) prefixo para o "B" A cláusula de comparação indica qualquer coisa antes desta corda e o asterisco do sufixo (*) da mesma forma qualquer coisa depois dessa corda. Podemos ver como b foi encontrado no primeiro abc string, mas não no segundo comando/string onde ADC foi usado como uma string de comparação.

Observe também como usamos [[...]] Suportes para o se declaração desta vez. Isso não está relacionado ao uso de sub -explosões, e é simplesmente um novo padrão de escrita mais novo se declarações que podem ser usadas para casos de uso adicionais ou outros, então para os tradicionais […] sintaxe. Exigimos aqui para fazer o especial b Combinando, estamos tentando, usando o asterisco (*) prefixo e sufixo para o "B" Compare a cláusula.

Em um se declaração com solteiro […] Suportes isso falharia:

$ se ["abc" == * "b" *]; Então eco!'; else eco 'não corresponde!'; Fi não corresponde! $ se [["abc" == * "b" *]]; Então eco!'; else eco 'não corresponde!'; FI corresponde! 

Enquanto o se [… ] A sintaxe não reconhece o asterisco (*) prefixo e sufixo para o "B" Compare a cláusula, e é preciso usar [[...]] Em vez disso, parênteses.

Outra coisa a observar é que desta vez usamos citações duplas (") dentro da subshell (em vez das citações únicas como no primeiro exemplo): quando se inicia uma subshell, esse uso de citações duplas não é apenas permitido, mas posso recomendá -lo para vários casos de uso. É útil em algumas situações em que muita análise complexa está acontecendo e uma mistura de citações únicas e duplas é necessária. As citações duplas não terão encerrar as citações iniciadas antes e fora da subshell.

Observe que, com a maioria dos exemplos anteriores, alguém poderia simplesmente deixar de lado a subshell e fazer uma comparação simples diretamente, por exemplo, a variável, i.e.:

$ Var1 = "abc"; se [["$ var1" == * "b" *]]; Então eco!'; else eco 'não corresponde!'; FI corresponde! 

Escolhemos, no entanto, para introduzir subshells com eco (efetivamente uma operação nula, eu.e. efetivamente o mesmo que apenas usar a variável ou o texto em questão), pois destacaria que 1) sub -mais de subsídios funcionam de maneira eficaz e 2) que podem ser usados ​​de dentro se declarações.

Exemplo 3: Declarações de subshels avançadas se baseadas

Não precisamos restringir nosso uso de sub -explosão dentro se declarações para um único comando, nem para o uso de eco sozinho. Vamos fazer uma pequena configuração:

$ touch a $ ls -cor = nunca ./a | wc -l 1 


Criamos um arquivo chamado a, e contou o número de linhas (usando wc -l, uma ferramenta de contagem que pode contar o número de linhas usando o -eu opção). Também nos certificamos de apresentar o --cor = nunca opção para ls Para evitar problemas de análise quando a codificação de cores do terminal é usada.

Em seguida, vamos trabalhar essas declarações diretamente em se declarações:

$ se [-z "$ (ls -cor = nunca ./a | wc -l) "]; então echo" saída de diretório vazio!"; fi $ se [" $ (ls - -cora = nunca ./a | wc -l) "-eq 1]; então eco" exatamente um arquivo encontrado!"; fi exatamente um arquivo encontrado! $ 

Aqui usamos o mesmo ls… wc -l código duas vezes diretamente de dentro de um se declaração. O primeiro se declaração, que usa -z verifica se o texto entre aspas (a primeira opção para o -z if-instruction) está vazio. Não é como o ls O comando produzirá alguma saída neste caso, já que criamos o arquivo a.

No segundo comando, na verdade testamos se a saída de nosso ls… wc -l O comando é igual a 1 usando o -Eq Opção de teste no se declaração. Eq apoia igual a. Observe que -Eq (e é reverso -ne ser não igual a) só pode ser usado para números. Para seqüências baseadas em texto, use == (igual) e != (não é igual) em vez disso.

A saída do comando (Exatamente um arquivo encontrado!) está correto e nosso se Declaração com subshell de vários comando incorporados funciona bem!

Também interessante notar que é que o primeiro valor de comparação no segundo se declaração (i.e. $ (ls -cor = nunca ./a | wc -l) com saída 1) é numérico. Então, por que usamos duas citações duplas ("...") em torno da declaração de subshell? Isso não tem nada a ver com subshells, e tudo com como se Funciona em Bash, e talvez não conheça esse truque ou taquigrafia; Por favor, considere isso:

$ V = "1 1" $ se [$ v -eq 0]; então eco '0'; FI BASH: [: muitos argumentos $ se ["$ v" -eq 0]; então eco '0'; FI BASH: [: 1 1: Expressão inteira esperada $ v = 0 $ se ["$ v" -eq 0]; então eco '0'; fi 0 

Em outras palavras, usar citações duplas é uma maneira um pouco mais segura de programar a festa se declarações, mesmo que a condição seja uma condição numérica. Ele protege contra seqüências mais complexas sendo interpretadas como itens individuais, em vez de um único valor, e retorna uma mensagem de erro correta (Expressão inteira esperada), em vez de mais ambíguo Bash: [: muitos argumentos erro.

Também não importa para fazer o que você está comparando o que parece ser uma string de texto (como indicado por "...") com um valor numérico; funciona, desde que o número seja numérico. E se não for, ainda fornecerá uma melhor mensagem de erro indicando que a string não é numérica, como visto. Em resumo, é melhor sempre citar sua subshell, texto ou variável com citações duplas, mesmo ao comparar itens numéricos. Para provar que isso funciona bem, considere:

$ se ["1" -eq "1"]; então ecoar 'y'; fi y $ se ["1" -eq "0"]; então ecoar 'y'; fi $ 

Conclusão

Neste artigo, analisamos a incorporação de subs -grandes bash dentro se declarações. Exploramos vários exemplos, de fácil a avançado, sobre como podemos usar subs -grandes se declarações. Também mergulhamos um pouco no uso de citações duplas ao comparar, mesmo quando comparar campos numéricos. Usando subshells dentro de outros comandos e, neste caso se Declarações é uma maneira poderosa de expandir suas habilidades de script de bash. Aproveitar!

Tutoriais do Linux relacionados:

  • Subshells avançados de Linux com exemplos
  • Subshells Linux para iniciantes com exemplos
  • Bash If Declarações: Se, Elif, caso contrário, então, FI
  • Mastering Bash Script Loops
  • Tutorial de depuração do GDB para iniciantes
  • Multi-thread Bash Script e Gerenciamento de Processos no…
  • Bash Loops com exemplos
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Variáveis ​​de bash especiais com exemplos