Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

231
Visualizações
¿Por qué Bash `(())` no funciona dentro de `[[]]`?
[[ " stop start status " =~ " $2 " && (($#<3)) ]] || { echo "Usage $0 file_name command"; exit 1;}

Con frecuencia uso la solución anterior para verificar el rango de entrada de mi script Bash.

Ahora me doy cuenta de que la expresión aritmética extendida (()) parece estar suprimida dentro del corchete doble [[]] .

Para ilustrar el problema:

 a=start; n=1; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad ok a=start; n=5; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad bad # But: a=start; n=100; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad ok

El resultado anterior es falso porque n no es menor que 3 si se tratan como números. Esta es la solución correcta:

 a=start; n=100; [[ " stop start status " =~ " $a " ]] && (($n<3)) && echo ok || echo bad bad a=start; n=1; [[ " stop start status " =~ " $a " ]] && (($n<3)) && echo ok || echo bad ok
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

La página de manual de GNU bash para [[..]] explica que el operador ejecuta una expresión condicional y

Devuelve un estado de 0 o 1 dependiendo de la evaluación de la expresión condicional expression . Las expresiones se componen de los primarios que se describen a continuación en Expresiones condicionales de Bash .

Pero el operador aritmético no es parte de las expresiones condicionales compatibles ( primarias ) dentro de [[..]] lo que significa que la expresión se ve obligada a ejecutarse como una comparación de cadenas, es decir

 (( $n < 3))

no se ejecuta en un contexto aritmético sino en una comparación lexicográfica (cadena) tan simple como

 [[ 100 < 3 ]]

que siempre resultará verdadero, porque los valores ASCII para 1 , 0 , 0 aparecen antes que 3

Pero dentro de [[..]] las operaciones aritméticas son compatibles si usa -lt , -gt

arg1 OP arg2

OP es uno de -eq , -ne , -lt , -le , -gt o -ge . Estos operadores binarios aritméticos devuelven verdadero si arg1 es igual a, no igual a, menor que, menor que o igual a, mayor que, o mayor que o igual a arg2 , respectivamente.

Entonces, ¿habías escrito tu expresión como

 a=start; n=100; [[ " stop start status " =~ " $a " && $n -lt 3 ]] && echo ok || echo bad bad

habría funcionado como se esperaba.

O incluso si hubiera forzado el uso de la expresión aritmética con el prefijo $ antes de ((..)) y lo hubiera escrito como se muestra a continuación (tenga en cuenta que bash no tiene un comportamiento documentado para $((..)) dentro de [[..]] ) . El comportamiento esperado probable es que la expresión aritmética se expanda antes de que se evalúe [[..]] y la salida resultante se evalúe en un contexto de cadena como [[ 0 ]] lo que significa una cadena no vacía.

 a=start; n=5; [[ " stop start status " =~ " $a " && $(( $n < 3 )) ]] && echo ok || echo bad

El resultado aún se vería mal, porque la expresión aritmética dentro de [[..]] se descompone en una cadena unaria, no una expresión de comparación vacía como

 $(( 5 < 3 )) 0 [[ -n 0 ]]

El operador de prueba toma el resultado de la evaluación aritmética 0 (falso) como una entidad distinta de cero y afirma que es verdadero en el lado derecho de && . Lo mismo se aplicaría para el otro caso también, por ejemplo, digamos n=1

 $(( 1 < 3 )) 1 [[ -n 1 ]]

En pocas palabras, use los operandos correctos para la operación aritmética dentro de [[..]] .

over 4 years ago · Santiago Trujillo Relatório

0

(( es una "palabra clave" que introduce la declaración aritmética. Sin embargo, dentro de [[ , no puede usar otras declaraciones. Sin embargo, puede usar paréntesis para agrupar expresiones, así que eso es (( ... )) : una "doble grupo". Los siguientes son todos equivalentes, debido a las precedencias de < y && :

  • [[ " stop start status " =~ " $2 " && (($#<3)) ]]
  • [[ " stop start status " =~ " $2 " && ($#<3) ]]
  • [[ " stop start status " =~ " $2 " && $#<3 ]]

Si desea una comparación de enteros, use -lt en lugar de < , pero tampoco necesita ajustar todo dentro de [[ ... ]] . Puede usar una declaración condicional y una declaración aritmética juntas en una lista de comandos.

 { [[ " stop start status " =~ " $2 " ]] && (($#<3)) ; } || { echo "Usage $0 file_name command"; exit 1;}

En este caso, ... && ... || ... funcionará de la manera esperada, aunque en general ese no es el caso. Prefiere una declaración if en su lugar.

 if [[ " stop start status " =~ " $2 " ]] && (($#<3)); then echo "Usage $0 file_name command" exit 1 fi
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda