Köşeli ayraçlar durumunda: neden boşluk olmadan sözdizimi hataları alıyorum?


17

Senaryo yılın iki günü başlarken iki gün geri taşımak ve aynı zamanda her ayın ilk ve ikinci günlerini kontrol ve iki gün geri taşımak için aşağıdaki komut dosyası kullanıyorum.

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

Ama benim hatam aşağıdaki hata mesajını alıyorum

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
Verilen cevaplar doğrudur; sonra boşluk gerekir [. Ayrıca, elififadeye bakın; işleri temizlemenize yardımcı olacaktır. Ayrıca, if ifadelerinden sonraki noktalı virgüller gerekli değildir, ancak yanlış da değildir, sadece gariptir.
Shawn J. Goff

@ ShawnJ.Goff Sonraki satırı ( if [ ... ]; then) birleştirirseniz gereklidir , bu yüzden sıra dışı değildir.
goldilocks

@ goldilocks, evet, bu benim tercih ettiğim tarz. Olağandışı olmasının nedeni, bunu yapmamasıdır.
Shawn J. Goff

Yanıtlar:


27

[ne bir metakarakter ne de bir kontrol operatörüdür (ayrılmış bir kelime bile değildir; aynı şey için ]), bu nedenle etrafında boşluk olması gerekir. Aksi takdirde kabuk komutu "görür" [01=01]komutunun yerine [ayrı parametreler ile 01, =, 01, ve ]. Her işleç ve işlenenin [komut için ayrı bir bağımsız değişken olması gerekir , bu nedenle işleçler için de boşluk gereklidir.

if [ "$month" = "01" ]

[$month="01"]$monthveya içindeki karakterlerden herhangi biriyle eşleşen bir joker karakter deseni "01. Hiçbir şeyle uyuşmuyorsa, yalnız bırakılır.

Kapatma köşeli ayraçtan sonra noktalı virgül varsa, noktalı virgül her zaman ayrı bir jetonun parçası olduğu için ondan önce bir alana ihtiyacınız yoktur.

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

Aynı şey bash (ve ksh ve zsh) çift parantez sözdizimi için de geçerlidir.

Birden fazla koşul

Koşulları birleştirmenin iki yolu vardır:

  1. içinde [

  2. veya [ile kombine edilmiş ayrı komutlarla&&||

Köşeli parantezlerle gruplamak muhtemelen içeride daha kolaydır [.

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

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

Birincisi güvenilmez olduğu için kaçınılmalıdır (örneğin ile deneyin month='!'). Önce güvenli dize (varsa) kullanılarak garip değişken içerikli sorunlar önlenebilir; veya [[/ ]]yerine [/ kullanarak ]:

if [ "01" = "$month" -a "01" = "$day" ]

[$ Month = "01"] && [$ day = "01"] gibi ay değeri == gün değeri gibi iki koşulu nasıl eşleştirebiliriz; 01 && 01
true'yu

@ AshokSanganahalli Cevabımı uzattım.
Hauke ​​Laging

1
[ne zaman -a/ -okullanılmaz hep POSIX uyumlu kabukları ile güvenilirdir. Kullanılması herhangi bir avantaj olursa olsun var -a/-oüzerinde &&/||. Kesinlikle onun kullanımını caydırırdım. [[POSIX olmadığını unutmayın .
Stéphane Chazelas

4

Yazmanın başka bir yolu:

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

1
İfade için +1 case. Birden fazla ürününüz elifvarsa, muhtemelen kullanıyor olmalısınız case.
HalosGhost

-1

Yani, bu cevabınız:

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

Yani köşeli ayraç ile değişken / değer arasına "boşluk" koymalısınız.


hayır i GUESS, çünkü komut dosyası yılın iki günü başlarken iki gün geri hareket etmesini istediğim gibi her ayın ilk ve ikinci günlerini kontrol edip iki gün geri hareket ederse burada [$ month = "01"] && [$ day = "01"] "01" ayını ve "01" ilk gününü eşleştirmeyi, o zamana geçmeyi veya başka bir duruma
geçmeyi varsayıyoruz

1
@AshokSanganahalli: Bunun nasıl ilişkili olduğunu bilmiyorum, ancak IF paranız çalışmıyor çünkü köşeli parantezler ve değer arasında "boşluk" yok
Neven

@AshokSanganahalli Beceri seviyenizdeki kişilerin, en azından ipucunu denemeden açıkça daha iyi anlaşılan kişilerden gelen düzeltmelere itiraz etmeleri genellikle iyi bir fikir değildir. Tahminleriniz doğru olsaydı, burada sormak zorunda kalmazdınız, değil mi?
Hauke ​​Laging

4
Alıntılanmamış değişkenler için -1 ve ==standart yerine kullanımı =.
Stéphane Chazelas

2
Soru bash etiketli değil. Eşitlik karşılaştırma operatörü standart [aka testkomutu olduğunu =. [eğer testler için herhangi bir ödev yapmaz, bu yüzden netleştirmeye gerek yoktur. Bazı [uygulamalar ==, standardın üzerinde bir uzantı olarak desteklenir , ancak hepsi değil. Örneğin , Bourne kabuğunun, ash's, posh' [s veya /bin/[bazı sistemleri yoktur. ==tarafından eklendi ksh, sanırım yeni (( ... ))yapısında aynı operatör ile tutarlılık için (hem = ve ==, ancak standart yok)
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.