if["$x"="valid"];then
echo "x has the value 'valid'"fi
Se você quiser fazer algo quando não corresponder, substitua =por !=. Você pode ler mais sobre operações de string e operações aritméticas na respectiva documentação.
Por que usamos aspas $x?
Você quer as aspas $x, porque se estiver vazio, seu script Bash encontrará um erro de sintaxe, como mostrado abaixo:
if[="valid"];then
Uso não padrão do ==operador
Observe que o Bash permite ==ser usado para igualdade com [, mas isso não é padrão .
Use o primeiro caso em que as aspas $xsão opcionais:
Como isso se relaciona com a resposta aceita dada no Erro inesperado do operador ? Eu recebi o mesmo erro ao usar [ "$1" == "on" ]. Alterar isso para ["$ 1" = "on"] resolveu o problema.
Piotr Dobrogost
78
Os espaços são necessários.
TAAPSogeking
6
@ JohnFeminella Ao escrever em um script bash, ele deve ter um único =e não dois.
User13107
73
pode valer a pena notar que você não pode usar [ $x -eq "valid" ]. -eqé o operador de comparação para números inteiros, não seqüências de caracteres.
craq
2
@ Alex, em que casos (se houver) eu preciso usar o padrão ["x$yes" == "xyes"], que é o prefixo da variável e da string literal com um x? Isso é uma relíquia dos velhos tempos ou é realmente necessário em algumas situações?
Agradecimentos para a string comparação ordem alfabética
shadi
Meu problema era que, $ana verdade, o " "envolvia como parte do valor literal da string, portanto, tive que usar o caractere de escape $bpara comparar os valores. Consegui encontrar isso após a execução bash -x ./script.sh, o sinalizador -x permite que você veja o valor de cada execução e ajuda na depuração.
ShahNewazKhan
Observe que a comparação de ordem alfabética não é padronizada pelo POSIX, portanto, não é garantido que funcione em plataformas não-GNU / shells não-bash. Somente as operações em pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html são garantidas como portáteis.
22718 Charles Duffy
62
Para comparar seqüências de caracteres com caracteres curinga, use
if[["$stringA"==*$stringB*]];then# Do something hereelse# Do Something herefi
É importante que os curingas possam ser usados apenas no lado direito! Observe também a falta "nos caracteres curinga. (btw: +1 para curingas!)
Scz
6
A expansão $stringBdeve ser citado (e, aliás, do lado esquerdo não precisa ser citado): if [[ $stringA = *"$stringB"* ]]; then.
gniourf_gniourf
Estou tentando usar a mesma lógica curinga para o nome do arquivo no caminho do arquivo. Mas não está funcionando para mim. tentei todas as diferentes seqüências de caracteres curinga fornecidas aqui. mas sempre vai para outro caso. stringA no meu caso é um caminho de arquivo / tmp / file e stringB é "file".
rain
35
Eu tenho que discordar de um dos comentários em um ponto:
["$x"=="valid"]&& echo "valid"|| echo "invalid"
Não, isso não é um delineador louco
É só que parece que um, hum, o não iniciado ...
Ele usa padrões comuns como uma linguagem, de certa forma;
E depois que você aprendeu o idioma.
Na verdade, é bom ler
É uma expressão lógica simples, com uma parte especial: avaliação lenta dos operadores lógicos.
["$x"=="valid"]&& echo "valid"|| echo "invalid"
Cada parte é uma expressão lógica; o primeiro pode ser verdadeiro ou falso, os outros dois são sempre verdadeiros.
(["$x"=="valid"]&&
echo "valid")||
echo "invalid"
Agora, quando é avaliado, o primeiro é verificado. Se for falso, então o segundo operando da lógica e&& depois não é relevante. O primeiro não é verdadeiro, portanto, não pode ser o primeiro e o segundo, de qualquer maneira.
Agora, nesse caso, é o primeiro lado da lógica ou|| falso, mas pode ser verdade se o outro lado - a terceira parte - for verdadeiro.
Portanto, a terceira parte será avaliada - principalmente escrevendo a mensagem como efeito colateral. (Tem o resultado 0para true, que não usamos aqui)
Os outros casos são semelhantes, mas mais simples - e - eu prometo! são - podem ser - fáceis de ler!
(Eu não tenho um, mas acho que ser um veterano do UNIX com barba grisalha ajuda muito nisso.)
A ... && ... || ...é geralmente desaprovam (greybeard pena Unix veterano, você esteve errado por todo esse tempo), como não é semanticamente equivalente a if ... then ... else .... Não se preocupe, isso é uma armadilha comum .
gniourf_gniourf
6
@gniourf_gniourf O OP não está errado - e eles provavelmente não são ignorantes, como você sugere. ... && ... || ...é um padrão perfeitamente válido e um idioma comum do bash. O uso prescreve conhecimentos prévios (o que pode ser bom ter em mente se houver iniciantes na platéia), mas o OP tem o cabelo para provar que eles sabem como evitar as tampas de bueiros abertas.
Ebpa 3/17
3
@ebpa E se a instrução a seguir && retornar um valor false, a execução prosseguirá para a instrução a seguir || ? Se assim o que está errado e, talvez, é o que gniourf está sugerindo
TSG
4
Eu pensei que eco fosse apenas um exemplo. A declaração seguinte && ainda pode retornar um valor diferente de zero
TSG
2
@gniourf_gniourf +1 por postar o link para Bash Pitfalls! Muito útil!
@ytpillai, é equivalência. Lembre-se de que você pode ter padrões separados por |antes do ). A ininstrução é equivalente a thenem ifinstruções. Você poderia argumentar que funciona sobre uma lista de padrões, onde cada lista tem sua própria declaração do que fazer, se você é do Python. Não gosto substring in string, mas sim for item in list. Use a *como sua última declaração se desejar uma elsecondição. Retorna no primeiro encontro.
mazunki
18
O script a seguir lê de um arquivo chamado "testonthis" linha por linha e, em seguida, compara cada linha com uma string simples, uma string com caracteres especiais e uma expressão regular. Se não corresponder, o script imprimirá a linha, caso contrário não.
O espaço no Bash é muito importante. Portanto, o seguinte funcionará:
["$LINE"!="table_name"]
Mas o seguinte não:
["$LINE"!="table_name"]
Então, por favor, use como está:
cat testonthis |while read LINE
doif["$LINE"!="table_name"]&&["$LINE"!="--------------------------------"]&&[["$LINE"=~[^[:space:]]]]&&[["$LINE"!= SQL*]];then
echo $LINE
fidone
Use esta abordagem para passar por um arquivo. Ou seja, remova o UUoC entre outras coisas.
fedorqui 'Então pare de prejudicar'
Não é importante por causa bashmas porque [é realmente um binário externo (como em which [rendimentos algo como /usr/bin/[)
Patrick Bergner
11
Eu provavelmente usaria correspondências regexp se a entrada tiver apenas algumas entradas válidas. Por exemplo, apenas o "start" e "stop" são ações válidas.
para mim (mac GNU bash versão 4.4.12 (1) -release x86_64-apple-darwin17.0.0), eu tenho que usar if [ "$a"="$b" ]ou ele não funciona ... não pode ter espaços em torno dos iguais
espectro
1
Fiz dessa maneira que é compatível com Bash e Dash (sh):
testOutput="my test"
pattern="my"case $testOutput in(*"$pattern"*)
echo "if there is a match"
exit 1;;(*)! echo there is no coincidence!;;esac
Respostas:
Usando variáveis em instruções if
Se você quiser fazer algo quando não corresponder, substitua
=
por!=
. Você pode ler mais sobre operações de string e operações aritméticas na respectiva documentação.Por que usamos aspas
$x
?Você quer as aspas
$x
, porque se estiver vazio, seu script Bash encontrará um erro de sintaxe, como mostrado abaixo:Uso não padrão do
==
operadorObserve que o Bash permite
==
ser usado para igualdade com[
, mas isso não é padrão .Use o primeiro caso em que as aspas
$x
são opcionais:ou use o segundo caso:
fonte
[ "$1" == "on" ]
. Alterar isso para ["$ 1" = "on"] resolveu o problema.=
e não dois.[ $x -eq "valid" ]
.-eq
é o operador de comparação para números inteiros, não seqüências de caracteres.["x$yes" == "xyes"]
, que é o prefixo da variável e da string literal com umx
? Isso é uma relíquia dos velhos tempos ou é realmente necessário em algumas situações?Ou, se você não precisar de outra cláusula:
fonte
echo
pode falhar.[ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid"
.{ echo invalid && false; }
é mais eficiente do que( echo invalid && false )
, pois evita pagar por um subshell desnecessário.Notas:
if
e[
e]
são importantes>
e<
são operadores de redirecionamento, portanto, escape-o com\>
e\<
respectivamente para cadeias.fonte
$a
na verdade, o" "
envolvia como parte do valor literal da string, portanto, tive que usar o caractere de escape$b
para comparar os valores. Consegui encontrar isso após a execuçãobash -x ./script.sh
, o sinalizador -x permite que você veja o valor de cada execução e ajuda na depuração.Para comparar seqüências de caracteres com caracteres curinga, use
fonte
"
nos caracteres curinga. (btw: +1 para curingas!)$stringB
deve ser citado (e, aliás, do lado esquerdo não precisa ser citado):if [[ $stringA = *"$stringB"* ]]; then
.Eu tenho que discordar de um dos comentários em um ponto:
Não, isso não é um delineador louco
É só que parece que um, hum, o não iniciado ...
Ele usa padrões comuns como uma linguagem, de certa forma;
E depois que você aprendeu o idioma.
Na verdade, é bom ler
É uma expressão lógica simples, com uma parte especial: avaliação lenta dos operadores lógicos.
Cada parte é uma expressão lógica; o primeiro pode ser verdadeiro ou falso, os outros dois são sempre verdadeiros.
Agora, quando é avaliado, o primeiro é verificado. Se for falso, então o segundo operando da lógica e
&&
depois não é relevante. O primeiro não é verdadeiro, portanto, não pode ser o primeiro e o segundo, de qualquer maneira.Agora, nesse caso, é o primeiro lado da lógica ou
||
falso, mas pode ser verdade se o outro lado - a terceira parte - for verdadeiro.Portanto, a terceira parte será avaliada - principalmente escrevendo a mensagem como efeito colateral. (Tem o resultado
0
para true, que não usamos aqui)Os outros casos são semelhantes, mas mais simples - e - eu prometo! são - podem ser - fáceis de ler!
(Eu não tenho um, mas acho que ser um veterano do UNIX com barba grisalha ajuda muito nisso.)
fonte
... && ... || ...
é geralmente desaprovam (greybeard pena Unix veterano, você esteve errado por todo esse tempo), como não é semanticamente equivalente aif ... then ... else ...
. Não se preocupe, isso é uma armadilha comum .... && ... || ...
é um padrão perfeitamente válido e um idioma comum do bash. O uso prescreve conhecimentos prévios (o que pode ser bom ter em mente se houver iniciantes na platéia), mas o OP tem o cabelo para provar que eles sabem como evitar as tampas de bueiros abertas.você também pode usar caso de uso / esac
fonte
|
antes do)
. Ain
instrução é equivalente athen
emif
instruções. Você poderia argumentar que funciona sobre uma lista de padrões, onde cada lista tem sua própria declaração do que fazer, se você é do Python. Não gostosubstring in string
, mas simfor item in list
. Use a*
como sua última declaração se desejar umaelse
condição. Retorna no primeiro encontro.O script a seguir lê de um arquivo chamado "testonthis" linha por linha e, em seguida, compara cada linha com uma string simples, uma string com caracteres especiais e uma expressão regular. Se não corresponder, o script imprimirá a linha, caso contrário não.
O espaço no Bash é muito importante. Portanto, o seguinte funcionará:
Mas o seguinte não:
Então, por favor, use como está:
fonte
bash
mas porque[
é realmente um binário externo (como emwhich [
rendimentos algo como/usr/bin/[
)Eu provavelmente usaria correspondências regexp se a entrada tiver apenas algumas entradas válidas. Por exemplo, apenas o "start" e "stop" são ações válidas.
Observe que eu minúscula a variável
$ACTION
usando as vírgulas duplas. Observe também que isso não funcionará em versões muito antigas do bash por aí.fonte
Bash 4+ exemplos. Nota: não usar aspas causará problemas quando as palavras contiverem espaços, etc. Sempre cite no Bash, IMO.
Aqui estão alguns exemplos no Bash 4+:
Exemplo 1, verifique 'yes' na string (não faz distinção entre maiúsculas e minúsculas):
Exemplo 2, verifique 'yes' na string (não faz distinção entre maiúsculas e minúsculas):
Exemplo 3, verifique se 'yes' na string (diferencia maiúsculas de minúsculas):
Exemplo 4, verifique se 'yes' na string (diferencia maiúsculas de minúsculas):
Exemplo 5, correspondência exata (diferencia maiúsculas de minúsculas):
Exemplo 6, correspondência exata (sem distinção entre maiúsculas e minúsculas):
Exemplo 7, correspondência exata:
Aproveitar.
fonte
if [ "$a"="$b" ]
ou ele não funciona ... não pode ter espaços em torno dos iguaisFiz dessa maneira que é compatível com Bash e Dash (sh):
fonte
(
e não usá-lo?