Bagaimana cara menggunakan kueri If-Else berdasarkan pada hari dalam seminggu?

10

Masalah: Saya perlu memeriksa apakah hari ini hari Kamis dan melakukan tindakan yang berbeda berdasarkan hasil dari kondisi ini. Saya mencoba dua pendekatan berbeda:

Mendapatkan Nama Hari:

DAYOFWEEK=$(date +"%a")
echo DAYOFWEEK: $DAYOFWEEK
if ["$DAYOFWEEK" == "Thu"]; 
then   
   echo YES
else
    echo NO
fi

Mendapatkan Jumlah Hari:

DAYOFWEEK=$(date +"%u")
echo DAYOFWEEK: $DAYOFWEEK

if ["$DAYOFWEEK" == 4]; 
then
   echo YES
else
   echo NO
fi

Dalam kedua kasus, outputnya adalah TIDAK, walaupun harus YA. Apa yang salah?

Swagatika
sumber
1
Catatan tambahan: itu ;akan diperlukan jika Anda memiliki thendi baris yang sama dengan if. Dalam hal ini mereka berlebihan.
manatwork

Jawaban:

12

Masalahnya adalah kosong yang hilang.

Kode berikut akan bekerja di shell yang [perintah bawaannya menerima ==sebagai alias untuk =:

if [ "$DAYOFWEEK" == 4 ];  then    echo YES; else    echo NO; fi

Namun perlu diingat (lihat help testdi bash):

  • ==tidak disebutkan secara resmi, Anda harus menggunakan =untuk membandingkan string
  • -eqdimaksudkan untuk tes aritmatika desimal (tidak akan membuat perbedaan di sini untuk date +%utetapi akan date +%dmisalnya ketika datang untuk membandingkan 04dan 4yang secara numerik sama tetapi berbeda secara leksikal).

Saya akan lebih memilih:

 if [ "${DAYOFWEEK}" -eq 4 ];  then    echo YES; else    echo NO; fi

Secara umum Anda harus memilih pendekatan angka hari , karena memiliki lebih sedikit ketergantungan ke lokal saat ini . Pada sistem saya, outputnya date +"%a"hari ini Do.

H.-Dirk Schmitt
sumber
3

Jangan mengabaikan caseyang seringkali merupakan cara yang lebih baik untuk melakukan hal-hal seperti ini:

Berhati-hatilah juga bahwa keluaran dari date +%abergantung pada lokal, jadi jika Anda mengharapkan nama-nama bahasa Inggris, skrip Anda akan berhenti berfungsi ketika dipanggil oleh pengguna Prancis atau Korea misalnya.

case $(LC_ALL=C date +%a) in
   (Mon) echo first day of the week;;
   (Thu) do-something;;
   (Sat|Sun) echo week-end;;
   (*) echo any other day;; # last ;; not necessary but doesn't harm
esac

Perhatikan bahwa di atas adalah salah satu kasus yang jarang terjadi di mana itu $(...)tidak perlu dikutip (meskipun kutipan tidak akan merugikan. Sama seperti di var="$(...)").

Stéphane Chazelas
sumber
0

Dalam ide yang sama, saya menggunakan kode berikut untuk "menonaktifkan" cron sebelum jam yang dipilih.
Tentu saja, saya lebih suka memodifikasi crontab itu sendiri ... jika saya diberikan hak yang diperlukan untuk :)

Berikut ini adalah tes sederhana yang membatalkan skrip bash kecuali kami di malam hari.

# Delay or restrict execution.
# Here, we quit unless hour is greater than (gt) 2 and (-a) lower than (lt) 7
# i.e. execution happens only at 3,4,5&6 o'clock.
if  /usr/bin/test `date '+%H'` -gt 2 -a `date '+%H'` -lt 7; then
  echo LETS_START_PROCESSING;
else
  exit;
fi

#Put job here
Balmipour
sumber
Mengapa menggunakan /usr/bin/testalih-alih [perintah bawaan shell ?
Stéphane Chazelas
@ Stéphane Chazelas Saya tidak menggunakan 3,4,5,6 karena saya tidak memiliki akses ke crontab. ( ini adalah baris ke-2 dari posting saya :) Server kami dikelola oleh Claranet, dan kami sudah kehilangan satu minggu tiket-ping-pong untuk mendapatkan ... cron yang berfungsi (tidak bercanda). Jadi kami menghindari mengacaukan dan membuka kembali tiket ketika kami bisa :) Untuk alasan itu, kami meminta tugas cron per jam alih-alih setiap hari, dan sampai semua tes kami selesai, akan lebih mudah untuk tidak menyentuh tugas itu, dan tambahkan kontrol kami di skrip yang dieksekusi.
Balmipour
Ah OK, maaf, saya pikir Anda berarti Anda tidak memiliki hak untuk memodifikasi cronexecutable dibandingkan dengan crontab pengguna.
Stéphane Chazelas
@ Stéphane Chazelas Tentang sintaks tes, saya lebih suka daripada [] atau [[]] karena saya mencoba skrip saya pada beberapa server lain terlebih dahulu, di mana saya bisa menggunakan crontab. Setelah terlalu banyak kejutan dengan crons, saya terbiasa menggunakan jalur absolut sebanyak mungkin di crontab. Orang mungkin mengatakan itu membuat tes jelek, dan akan benar ... tapi saya akan menjawab bahwa tes shell selalu jelek, dan akan benar juga ^^ Yang penting bagi saya adalah kebanyakan memiliki jawaban yang akan bekerja dengan salin / tempel sederhana, dan sertakan beberapa penjelasan.
Balmipour
1
Catatan yang -asudah usang di test. Secara standar, Anda akan menggunakan: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](atau hour=`date +%H`jika Anda harus kompatibel dengan cangkang Bourne, yaitu Solaris 10 dan lebih tua dan mungkin beberapa penyatuan SCO yang langka saat ini)
Stéphane Chazelas
0

Untuk menghentikan skrip di hari minggu, hapus saja baris hari:

DAYOFWEEK=$(date +"%u")
echo "$DAYOFWEEK";
if [ "$DAYOFWEEK" == 1 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 2 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 3 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 4 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 5 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 6 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 7 ]; then exit; else echo; fi
Daniel FR César
sumber
Selamat datang di Unix SE! Saya tidak yakin apakah saya memahami baris pertama Anda dengan benar. Bukankah lebih if [ "$DAYOFWEEK" -lt 7 ]baik?
peterh
-1

Pertama, Anda harus mengutip tugas DAYOFWEEK = "$ (tanggal +% u)"

Dan Anda perlu memiliki ruang di setiap sisi tanda kurung [dan].

Semi-kolon di ujung garis mubazir.

Johan
sumber
1
Kutipan tidak diperlukan.
H.-Dirk Schmitt
Untuk memperluas komentar @ H.-DirkSchmitt: alasan mengapa kutipan tidak diperlukan adalah bahwa output tidak akan mengandung spasi.
CVn
@ MichaelKjörling: Tidak - tidak pernah dibutuhkan ;-) Coba contoh:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt
@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $adengan beberapa spasi di antara digit (StackExchange tidak akan membiarkan saya membuatnya menjadi copy-and-paste sederhana, sayangnya).
CVn
@ MichaelKjörling - see man bash "Jika substitusi muncul dalam tanda kutip ganda, pemisahan kata dan perluasan nama path tidak dilakukan pada hasil." Jadi itu membuat dalam kasus pertanyaan dan contoh "1 2 3" tidak ada perbedaan.
H.-Dirk Schmitt