jika kondisi pada beberapa baris dalam bash shell

19

Saya memiliki fungsi bash shell yang mengambil argumen dan melakukan sesuatu di atasnya jika diperlukan.

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

Saya ingin memanggil metode ini dengan beberapa argumen dan memeriksa apakah setidaknya salah satu dari mereka berhasil.

Saya mencoba sesuatu seperti:

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

Apa yang akan menjadi sintaks yang benar untuk itu?
SUNTING
Juga - Saya ingin memastikan bahwa meskipun kondisi pertama benar semua kondisi lainnya masih akan dievaluasi.

Terima kasih,

Tidak apa-apa
sumber
Saya telah memperbarui jawaban saya.
tectux
Terima kasih, bisakah Anda memberikan contoh?
Itay
1
Saya telah menambahkan contoh kode ke jawaban saya.
tectux

Jawaban:

7

Jalankan perintah terlebih dahulu, lalu periksa apakah setidaknya salah satu dari mereka berhasil.

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi
geirha
sumber
3
Ini membingungkan, saya akan senang jika Anda dapat memberikan beberapa penjelasan tentang bagaimana pernyataan bersyarat bekerja di bash ..., do_something mengembalikan 0 setelah berhasil, tetapi kemudian kami memperbarui keberhasilan ke 1 ..., if ((success))mengevaluasi sesuatu yang berbeda dari if success. Saya bingung :)
Itay
2
@Itu ((...))adalah perintah aritmatika. Jika hasilnya di dalam, bukan nol, hasilnya benar (0). Jika hasilnya di dalam adalah 0, itu mengembalikan false (1). "sukses" diperlakukan sebagai variabel yang diharapkan mengandung angka. Lihat mywiki.wooledge.org/ArithmeticExpression
geirha
Terima kasih, saya kira bagian yang membingungkan saya adalah 0 benar dan 1 salah biasanya sebaliknya :)
Itay
2
@Itu Ya, mungkin membingungkan pada awalnya. Bash berbeda dari bahasa tujuan umum yaitu "berbasis perintah"; tidak memanggil fungsi, tidak memiliki kelas dan metode, menjalankan perintah, dan menguji status keluar perintah. Dan jauh lebih mudah untuk menjalankan perintah dalam bash daripada bahasa seperti C, python, java, perl, dll. Perintah keluar dengan 0 untuk memberi sinyal keberhasilan, dan 1-255 untuk berbagai jenis kegagalan. (Perintah umumnya hanya bisa berhasil dalam satu cara, tetapi gagal karena berbagai alasan berbeda)
geirha
2
Solusi ini memiliki keuntungan bahwa Anda dapat mengomentari baris yang tidak ingin Anda nonaktifkan sementara
Josiah Yoder
31

Gunakan garis miring terbalik.

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

EDIT

Juga - saya ingin memastikan bahwa meskipun kondisi pertama benar semua kondisi lainnya masih akan dievaluasi.

Itu tidak mungkin hanya dalam satu pernyataan jika. Alih-alih, Anda dapat menggunakan for for yang mengulang argumen dan mengevaluasinya secara terpisah. Sesuatu seperti:

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}
tectux
sumber
terima kasih, mencobanya - Saya mendapatkan kesalahan[: do_something: unary operator expected
Itay
Apakah Anda menempatkan setiap evaluasi di antara kurung sendiri? Jadi, [ expr1 ] || [ expr2 ]bukannya [ expr1 || expr2 ].
tectux
ya, saya lakukan: (...
Itay 11'13
Dugaan saya adalah yang do_something "arg1"ditafsirkan sebagai dua argumen sedangkan ekspresi harusnya unary. Adakah cara membuat do_something "arg1"dievaluasi sebagai satu argumen?
Itay
1
Kamu benar. Ini bekerja terlalu: if [ $(do_something "arg1") ].
tectux
5

Sintaks yang benar adalah:

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ digunakan untuk memberi tahu shell perintah berlanjut di baris berikutnya.

EDIT : Saya pikir ini harus melakukan apa yang Anda inginkan:

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"
Eric Carvalho
sumber
Terima kasih, hasil dengan kesalahan:[: too many arguments
Itay
@ Jawaban Jawaban telah diperbarui.
Eric Carvalho
Memperbarui pertanyaan - ini belum merupakan jawaban terakhir :(
Itay
-1

Aku lebih memilih:

if {
    do_something "arg1" ||
    do_something "arg2" ||
    do_something "arg3"
}; then
    echo "OK"
else
    echo "NOT OK"
fi
Toxiro
sumber
Script Anda tidak akan berfungsi sama sekali: setelah parameter pengujian 1, itu akan menghasilkan \nkarakter, sehingga ifpernyataan Anda akan menghasilkan beberapa kesalahan, dan do_somethingbukan perintah nama, sehingga lebih banyak kesalahan
damadam
Bagi saya ini berfungsi dalam zsh dan bash, IF do_somethingadalah fungsi tentunya. do_somethingharus fungsi atau perintah, apa lagi yang seharusnya? Selain itu saya tidak melihat di mana ia akan menghasilkan \nkarakter kecuali setelah menggemakan hasilnya dan ini diharapkan ...
Toxiro