Bash jika pernyataan dengan berbagai kondisi melempar kesalahan

165

Saya mencoba menulis sebuah skrip yang akan memeriksa dua flag kesalahan, dan jika satu flag (atau keduanya) diubah itu akan echo-- kesalahan terjadi. Skrip saya:

my_error_flag=0
my_error_flag_o=0
do something.....
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" &&     "$my_error_flag_o"="2" ]]; then
    echo "$my_error_flag"
else
    echo "no flag"
fi

Pada dasarnya, seharusnya, sesuatu:

if ((a=1 or b=2) or (a=1 and b=2))
  then
     display error
else
     no error
fi

Kesalahan yang saya dapatkan adalah:

 line 26: conditional binary operator expected
 line 26: syntax error near `]'
 line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then'

Apakah kurung saya berantakan?

Simply_me
sumber
2
Gunakan tanda kurung - ()
AlikElzin-kilaka
3
Logikanya, a==1 or b==2sudah mencakup case mana a==1 and b==2. Menguji secara terpisah untuk itu benar-benar berlebihan di sini.
tripleee

Jawaban:

248

Gunakan -a(untuk dan) dan -o(untuk atau) operasi.

tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

Memperbarui

Sebenarnya Anda masih bisa menggunakan &&dan ||dengan -eqoperasi. Jadi skrip Anda akan seperti ini:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then
      echo "$my_error_flag"
else
    echo "no flag"
fi

Meskipun dalam kasus Anda, Anda dapat membuang dua ekspresi terakhir dan tetap dengan satu atau operasi seperti ini:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ]; then
      echo "$my_error_flag"
else
    echo "no flag"
fi
mkhatib
sumber
3
@Simply_Me: Tidak, OR logis adalah benar jika salah satu atau kedua operandnya benar. Anda berpikir "eksklusif atau" (XOR), yang benar jika salah satu operannya benar. (Sebenarnya, ada versi XOR yang bekerja pada lebih dari 2 operan, dalam hal ini benar jika jumlah aneh operan benar.)
Gordon Davisson
4
BTW, masalah dalam kode asli termasuk menggunakan [dan ]untuk pengelompokan (mereka tidak melakukan itu), dan gagal menempatkan spasi di sekitar operator (misalnya "$my_error_flag"="1"), yang mencegah shell dari mengenalinya sebagai operator sama sekali. Silakan baca BashFAQ # 17 (pada pengelompokan) dan # 31 (tentang perbedaan antara berbagai jenis ekspresi tes) . Sebenarnya, dalam hal ini akan lebih mudah untuk menggunakan ekspresi aritmatika .
Gordon Davisson
7
-adan -odianggap usang oleh spesifikasi POSIX ; gunakan tes terpisah dikombinasikan dengan ||seperti dalam pembaruan.
chepner
1
Tidak perlu mengelompokkan menggunakan subkulit, biasanya pengelompokan menggunakan {}juga dimungkinkan.
phk
1
untuk menambahkan komentar phk di atas, () meluncurkan subshell di bash, yang dapat memiliki segala macam efek [mungkin tidak diinginkan] yang halus.
brett
70

Anda dapat menggunakan salah satu [[atau ((kata kunci. Bila Anda menggunakan [[kata kunci, Anda harus operator menggunakan tali seperti -eq, -lt. Saya pikir, ((paling disukai untuk aritmatika, karena Anda dapat langsung menggunakan operator seperti ==, <dan >.

Menggunakan [[operator

a=$1
b=$2
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]]
then
     echo "Error"
else
     echo "No Error"
fi

Menggunakan ((operator

a=$1
b=$2
if (( a == 1 || b == 2 )) || (( a == 3 && b == 4 ))
then
     echo "Error"
else
     echo "No Error"
fi

Jangan gunakan -aatau -ooperator Karena tidak Portable.

Fizer Khan
sumber
8

Silakan coba ikuti

if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ;
then
    echo "WORKING"
else
    echo "Out of range!"
Manash Nath
sumber
2
( ... )menciptakan subkulit - banyak dampak kinerja tanpa manfaat.
Charles Duffy
4
Gunakan { ...; }untuk pengelompokan tanpa pembuatan subkulit.
Charles Duffy
1

Anda bisa mendapatkan inspirasi dengan membaca entrypoint.sh skrip yang ditulis oleh kontributor dari MySQL yang memeriksa apakah variabel yang ditentukan telah ditetapkan.

Seperti yang ditunjukkan skrip, Anda dapat mengirimnya dengan pipa -a, misalnya:

if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
    ...
fi
Daniel Andrei Mincă
sumber
1
-aditandai sebagai usang dalam versi teststandar POSIX saat ini ; lihat OBpenanda di pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Gunakan [ -z "$FOO" ] && [ -z "$BAR" ]untuk memiliki kode yang lebih andal.
Charles Duffy