bash: ho rotto [[<]]


14

Stavo scrivendo uno script bash e improvvisamente questo comportamento è iniziato:

[[ 1 < 2 ]]; echo $?  # outputs 0
[[ 2 < 13 ]]; echo $? # outputs 1

ma -ltfunziona bene:

[[ 1 -lt 2 ]]; echo $?  # outputs 0
[[ 2 -lt 13 ]]; echo $? # outputs 0

ho sovrascritto accidentalmente in <qualche modo?

ecco uno script che ho scritto per testare questo comportamento:

#!/bin/bash

for a in {1..5}
do
    for b in {1..20}
    do
        [[ $a < $b ]] && echo $a $b
    done

    echo
done

ecco l'output:

1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20

2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 20

3 4
3 5
3 6
3 7
3 8
3 9

4 5
4 6
4 7
4 8
4 9

5 6
5 7
5 8
5 9

la modifica <a -ltnello script fornisce un output normale ( 5 10visualizzato ad esempio).

Il riavvio non ha cambiato nulla.

La mia versione bash è GNU bash, versione 4.3.42 (1) -release (x86_64-pc-linux-gnu). Sono su Ubuntu 15.10. Non so quali altre informazioni siano rilevanti qui.


16
con l' <operazione stai facendo un confronto di stringhe, mentre l' -ltoperatore è un confronto numerico, se guardi i risultati che hai elencato, te ne accorgerai. Numericamente 2 è meno di 10, in ordine alfabetico, viceversa.
MelBurslan,

Risposte:


51

Dalla bashpagina man.

Se utilizzati con [[, gli operatori <e> ordinano lessicograficamente utilizzando le impostazioni internazionali correnti.

Dall'output, sembra funzionare come previsto.


35
In altre parole, leggi la pagina man prima di presumere di aver trovato un bug. ;)
Wildcard

Vero. Forse lo script a cui stavo lavorando in origine ha iniziato a funzionare in modo "corretto" (come in mancanza di [[$ myvar <13]]) quando ho notato questo comportamento. C'è qualcosa che dovrei fare ora a questa domanda? In questo sito cambiamo il titolo per includere [risolto] o qualcosa del genere? Il titolo dovrebbe comunque essere cambiato in qualcosa di più descrittivo?
snail-on-a-quest

2
No, non modificare il titolo della domanda. Il segno di spunta accanto a questa risposta è sufficiente per indicare che la domanda è stata risolta.
saiarcot895,

14
@Wildcard L'OP non presume di aver trovato un bug. Suggeriscono esplicitamente che forse hanno fatto qualcosa per alterare il comportamento. Anche il titolo assume altrettanto!
jpmc26,

5

Che ne dite di:

for a in {1..5}; 
do     
  for b in {1..20};     
  do         
    (( $a < $b )) && echo $a $b
  done      
  echo
done

Secondo http://www.tldp.org/LDP/abs/html/dblparens.html

Simile al comando let, il costrutto ((...)) consente l'espansione e la valutazione aritmetica. Nella sua forma più semplice, a = $ ((5 + 3)) imposterebbe a 5 + 3 o 8. Tuttavia, questo costrutto tra parentesi doppie è anche un meccanismo per consentire la manipolazione delle variabili in stile C in Bash, ad esempio , ((var ++)).


2
Ti manca il punto della domanda: non è "come posso confrontare questi valori?" ma "perché si comporta così?".
Guntbert,

7
Questo è stato già risposto. Ma siccome voleva usare un'espressione aritmetica, varrebbe la pena sottolineare che esistono costrutti che ti permettono di usare quelli nella shell.
PaulSmecker,

3

In primo luogo, [[ non è POSIX e dovrebbe essere evitato.

In secondo luogo, se si desidera utilizzare <come parte di un test aritmetico, è possibile farlo, ma con una sintassi diversa:

if [ $((2 < 13)) = 1 ]
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi

O:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.