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,


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

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
}

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"

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.