Kurung dalam kondisi if: mengapa saya mendapatkan kesalahan sintaksis tanpa spasi putih?

17

Saya menggunakan skrip di bawah ini untuk mundur dua hari ketika skrip berjalan mulai dua hari dalam setahun dan juga memeriksa hari pertama dan kedua setiap bulan dan mundur dua hari.

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

Tapi salahku mendapat pesan kesalahan di bawah ini

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found
Kumar1
sumber
1
Jawaban yang diberikan benar; Anda perlu spasi putih setelah [. Selain itu, lihatlah elifpernyataannya; itu akan membantu Anda membersihkan segalanya. Juga, titik koma setelah pernyataan if tidak diperlukan, tetapi juga tidak salah, hanya aneh.
Shawn J. Goff
@ ShawnJ.Goff Mereka diperlukan jika Anda menyatukan baris berikutnya ( if [ ... ]; then), jadi itu tidak biasa.
goldilocks
@goldilocks, ya, itulah gaya yang saya sukai. Alasannya tidak biasa adalah karena dia tidak melakukan itu.
Shawn J. Goff

Jawaban:

27

[bukan metacharacter atau operator kontrol (bahkan bukan kata yang dilindungi undang-undang; sama untuk ]) sehingga diperlukan spasi di sekitarnya. Jika tidak shell "melihat" perintah [01=01]bukan perintah [dengan parameter yang terpisah 01, =, 01, dan ]. Setiap operator dan operan perlu menjadi argumen terpisah untuk [perintah, sehingga spasi juga diperlukan di sekitar operator.

if [ "$month" = "01" ]

[$month="01"]adalah pola wildcard yang cocok dengan salah satu karakter di $monthatau "01. Jika tidak cocok dengan apa pun, dibiarkan sendiri.

Jika ada titik koma setelah kurung tutup, Anda tidak perlu spasi sebelum itu, karena titik koma selalu menjadi bagian dari token yang terpisah.

if [ "$month" = "01" ]; then

Hal yang sama berlaku untuk sintaks braket ganda bash (dan ksh dan zsh).

Lebih dari satu syarat

Ada dua cara untuk menggabungkan kondisi:

  1. dalam [

  2. dengan [perintah terpisah dikombinasikan dengan &&atau||

Pengelompokan dengan tanda kurung mungkin lebih mudah di dalam [.

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

Yang pertama harus dihindari karena tidak dapat diandalkan (coba misalnya dengan month='!'). Masalah dengan konten variabel aneh dapat dihindari dengan menggunakan string aman (jika ada) terlebih dahulu; atau dengan menggunakan [[/ ]]bukannya [/ ]:

if [ "01" = "$month" -a "01" = "$day" ]
Hauke ​​Laging
sumber
Bagaimana kami dapat mencocokkan kedua kondisi dalam if, seperti nilai bulan == nilai hari jika [$ month = "01"] && [$ day = "01"]; Saya mengharapkan 01 && 01 benar kemudian mencetak di bawah kondisi atau pindah ke pernyataan lain
Kumar1
@AshokSanganahalli Saya telah memperpanjang jawaban saya.
Hauke ​​Laging
1
[ketika -a/ -otidak digunakan selalu dapat diandalkan dengan kerang yang sesuai dengan POSIX. Tidak ada apapun keuntungan dalam menggunakan -a/-olebih &&/||. Saya pasti akan mencegah penggunaannya. Perhatikan bahwa [[ini bukan POSIX.
Stéphane Chazelas
4

Cara lain untuk menulisnya:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac
Stéphane Chazelas
sumber
1
+1 untuk casepernyataan. Jika Anda memiliki lebih dari satu elif, Anda mungkin harus menggunakan case.
HalosGhost
-1

Jadi, inilah jawaban Anda:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

Jadi, Anda harus meletakkan "spasi" antara braket persegi dan variabel / nilai.

Neven
sumber
no i GUESS, karena ketika saya meminta skrip untuk mundur dua hari ketika skrip berjalan mulai dua hari dalam setahun dan juga memeriksa hari pertama dan kedua setiap bulan dan memindahkan dua hari ke belakang berarti di sini jika [$ bulan = "01"] && [$ day = "01"] kami seharusnya mencocokkan bulan "01" dan hari pertama "01" benar, pindah ke sana atau pindah ke kondisi lain
Kumar1
1
@AshokSanganahalli: Saya tidak tahu bagaimana ini terkait, tetapi kondisi IF Anda tidak berfungsi karena Anda tidak memiliki "ruang kosong" antara tanda kurung dan nilai
Neven
@AshokSanganahalli Biasanya bukan ide yang baik untuk orang-orang di tingkat keahlian Anda untuk membantah koreksi dari orang-orang dengan pemahaman yang jelas lebih baik tanpa setidaknya memberikan petunjuk mencoba. Jika tebakan Anda benar, maka Anda tidak perlu bertanya di sini, bukan?
Hauke ​​Laging
4
-1 untuk variabel yang tidak dikutip dan penggunaan ==bukannya standar =.
Stéphane Chazelas
2
Pertanyaannya bukan dengan tag bash. Operator perbandingan kesetaraan dalam perintah alias standar[test adalah =. [jika untuk tes, itu tidak melakukan tugas apa pun sehingga tidak perlu ambigu. Beberapa [implementasi mendukung ==sebagai perpanjangan atas standar, tetapi tidak semua. The Bourne shell ini, ash's, posh' s [s atau /bin/[dari beberapa sistem misalnya tidak. ==ditambahkan oleh ksh, saya kira untuk konsistensi dengan operator yang sama dalam (( ... ))konstruk baru (yang memiliki = dan ==, tetapi tidak ada standar)
Stéphane Chazelas