Bash'te "if" ifadesi için "ve" operatörü


168

Web sitesi kapalı olup olmadığını kontrol etmek için basit bir Bash komut dosyası oluşturmaya çalışıyorum ve bir nedenle "ve" operatörü çalışmıyor:

#!/usr/bin/env bash

WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="an@email.com"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"

if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
    echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi

"-A" operatörü de çalışmaz:

if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]

Ayrıca ne zaman kullanacağınızı da bildirir misiniz?

  • tek ve çift köşeli ayraçlar
  • parantez

?


3
Lütfen neyin işe yaramadığı konusunda daha kesin bilgi verir misiniz? Belirli bir hata mesajınız mı var, yoksa beklenen çıktıyı sağlamıyor mu?
— Julien Vivenot

Aslında "tekli operatör bekleniyordu" alıyordum bu yüzden alıntı yardımcı olur gibi görünüyor
— HTF

-ayineleniyor. Bourne kabuğu tarzı ile kullanıldığında testkomutu, aka [, bunun anlamı and. Koşullu ifade olarak kullanıldığında bir dosyanın var olup olmadığını test eder. Evet kafa karıştırıcı, en iyi kaçınılması.
— cdarke

Yanıtlar:


254

${STATUS}Boş olmadıkça sahip olduğunuz şey çalışmalıdır . Muhtemelen yapmak daha iyi olurdu:

if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then

veya

if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then

Söylemek zor, çünkü senaryonuzda neyin yanlış gittiğini bize tam olarak göstermediniz.

Kişisel görüş: asla kullanmayın [[. Önemli hata mesajlarını bastırır ve farklı kabuklara taşınabilir değildir.


2
Eğer STATUSboştur, @HTF kod başarısız olurdu -ne: unary operator expected. Senin durumunda, başarısız integer expression expectedolacak, değil mi?
— Julien Vivenot

1
Onu anlıyorum. Ancak $STATUSboş olabilecek sorunu vurgular ve bir çözüm önerirsiniz (alıntı yaparak). Çözümünüz hala boş bir şeyle başarısız oluyor STATUS, demek istediğim bu.
— Julien Vivenot

1
@jvivenot Bir noktan var. (Yorumunuza verdiğiniz yanıt, yorumunuzu düzenlemeden önce yapıldı, yorumunuz yalnızca "kod ... başarısız olurdu". Basit bir çözüm kullanmaktır ${STATUS:-0". Düzenleyecektir.
— William Pursell

Maalesef, düzenlemeniz hala çalışmıyor. Örneğin: STATUS=; [ $STATUS -ne 13 ] 2>/dev/null && echo fooolması gerekse foobile çıktı vermez (boş 13'ten farklıdır). İlk önerdiğiniz şey ${STATUS:-0}çok daha iyi görünüyor.
— Julien Vivenot

@jvivenot ${STATUS:-0}Eğer kullanılırsa başarısız olur STATUS=foo, ancak ! [ "$STATUS" -eq 200 ] 2> /dev/null && echo fooçalışır. IMO, kaçınmak -eqve kullanmak daha iyidir !=.
— William Pursell

28

Bunu dene:

if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then

benim için çalıştı. Bence birden fazla yol olabilir ama şimdilik bundan memnunum.
— Kushal Ashok

27

Bunu dene:

if [ ${STATUS} -ne 100 -a "${STRING}" = "${VALUE}" ]

veya

if [ ${STATUS} -ne 100 ] && [ "${STRING}" = "${VALUE}" ]

en temiz örnek için
— Pawel Cioch

12

Alıntı:

"-A" operatörü de çalışmaz:

[$ STATUS -ne 200] -a [["$ STRING"! = "$ VALUE"]]

Daha ayrıntılı bir açıklama için: [ve ]Bash'a ayrılmış kelimeler değildir. ifAnahtar kelime tanıttı koşullu bir iş tarafından değerlendirilecek (işin dönüş değeri ise koşullu doğrudur 0ya yanlış şekilde).

Önemsiz testler için testprogram ( man test) vardır.

Bazıları if test -f filename; then foo bar; fi, vb. Gibi sinir bozucu çizgiler bulduğunda , çoğu sistemde [aslında testprograma sadece bir sembolik bağlantı adı verilen bir program bulabilirsiniz . Ne zaman testolarak adlandırılır [, eklemek zorunda ]son pozisyonel argüman olarak.

Yani if test -f filenametemelde olarak (estiren süreçler açısından) aynıdır if [ -f filename ]. Her iki durumda da testprogram başlatılacak ve her iki süreç de aynı şekilde davranmalıdır.

İşte hatan: iş + kendisi hariç her şey + if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]ayrışacak . İş sadece basit bir komuttur (Bash tek bir işlemle sonuçlanan bir şey için konuşur), yani ilk kelime ( ) komuttur ve geri kalanı konumsal argümanlarıdır. İlkinden sonra geriye kalan tartışmalar var .ifif[]

Ayrıca [[, gerçekten bir Bash anahtar kelimesidir, ancak bu durumda, yalnızca normal bir komut argümanı olarak ayrıştırılır, çünkü komutun önünde değildir.

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.