Bir komut dosyasından koşullu ifadede nasıl çıkarım?


50

Kullanıcı root değilse, çıkmak istediğim bir bash betiği yazıyorum. Koşullu düzgün çalışıyor, ancak komut dosyası çıkmıyor.

[[ `id -u` == 0 ]] || (echo "Must be root to run script"; exit)

Kullanmak &&yerine her ;ikisini de kullanmayı denedim .

Yanıtlar:


50

Bunu bu şekilde yapabilirsin:

[[ $(id -u) -eq 0 ]] || { echo >&2 "Must be root to run script"; exit 1; }

(ilk ifadedeki bir aritmetik ikili operatör ile "sıradan" koşullu ifade), veya:

(( $(id -u) == 0 )) || { echo >&2 "Must be root to run script"; exit 1; }

(ilk test için aritmetik değerlendirme).

Değişiklik fark ()-> {}- kıvırcık parantezler yok değil bir altkabuk çalıştırmak. ( man bash"Alt kabuk" için arama yapın .)


1
Lütfen sıfırdan farklı bir kodla çıkın, örnek: exit 1Bir sorunun oluştuğu ana süreci anlamak için.
SamK

1
Sen kullanmamalısınız [[Sayısal karşılaştırma, kullanım için ((.
Chris Down,

1
@ChrisDown yerine [[kullandığınız sürece iyidir . -eq==
Let_Me_Be 24:11

Koşullu düzeltildi, aritmetik sürümü @ChrisDown eklendi.
Mat 24:11

2
@Mat Bu arada, kısaltabilirsin(( EUID )) && ...
Chris Down

21

Bu komutların etrafındaki parantezler bir alt kabuk yaratır . Alt kabuk ekosunuz "Komut dosyasını çalıştırmak için kök olmalıdır" ve sonra alt kabuktan çıkmasını söyleyin (daha önce komut olmadığından zaten olmuştu). Bunu düzeltmenin en kolay yolu muhtemelen sadece bir kullanmaktır if:

if [[ `id -u` != 0 ]]; then
    echo "Must be root to run script"
    exit
fi

Yani bunu bir gömlek ile yapmanın bir yolu yok mu?
Garrett Hall

1
mantığınız geriye doğru. senin örnekte, eğer id -u == 0, sen demek ki vardır kökü. Sen istiyorsun [[ $(id -u) != 0 ]]; then.
Tim Kennedy

4
Tek bir linere sahipseniz / olması gerekiyorsa, bunu boyut için deneyin: [ "$UID" != 0 ] && echo 'You have to be root.' && exit 1;Ayrıca $UID, bir işlemin yumurtlanmasından tasarruf edildiğine de dikkat edin . Bence tercih bile edersin $EUID.
janmoesen

1
@ janmoesen, iyi nokta. Ve çiş yaparken bir sayısal değere sahip bir değişken vardır: ((UID)) && echo 'You have to be root.' && exit 1.
Manatwork

3
@ janmoesen: Böyle bir ters mantık set -ekullanmanın iptal eden bir betiğe neden olacağına dikkat edin . Bu sorunun bir çözümü [ "$UID" != 0 ] && echo 'You have to be root.' && exit 1 || true.
sam hocevar,

2

İle bash :

[ $UID -ne 0 ] && echo "Must be root to run script" && exit 1

Bu başarısız echoolursa (örneğin stdout yazılabilir olmadığından) çıkmaz.
Stéphane Chazelas

1

Köşeli parantezler ||ve &&bunlar doğru bir ilişki olduğu için zorunlu değildir. Aşağıdaki iki ifade eşdeğerdir:

expr1 || expr2 && expr3
expr1 || { expr2 && expr3 }

Bunun &&yerine, gerçek ;gibi echodönecek gibi , sadece iyi çalışacaktı.

[[ $(id -u) == 0 ]] || echo "Must be root to run script" && exit 1

1
Söylediğiniz her şey doğru olsa da, öğrenmek için kötü bir kalıp çünkü expr2'nin dönüş değerine güveniyorsunuz. Echo'nun her zaman 0 çıkış durumu döndüreceğinden emin misiniz? İfadeleri küme ayraçları ve noktalı virgüllerle gruplamak daha iyi bir fikirdir. Bu, BashPitfalls'a kendi girişi olan yaygın bir tuzaktır
Flimm

1
@ Flimm: Bunun kötü bir kalıp olduğu konusunda hemfikir değilim. Açıkça, kullanımı büyük-küçük harf bağımlıdır ve ayrıca alacağınız getiri değerleri hakkındaki bilginize de bağlıdır. Bu durumda, echo değerinin% 99,999'u 0 döndüreceğinden eminim ve bir yazma hatasını durdurursa (yalnızca 0 döndürmeyecekse) bu ifade'den daha büyük bir sorun var. SİZİN geri dönüş değerleri oluşturduğun bir durum var, o yüzden hayır, benim için "kötü bir model" değil.
ata 11:11

Ben de ekleyeceğim, wikide yazdığı gibi, C değerlendirmesini anlamak için kesinlikle kullanmanız gerektiğini. Her neyse, küçük bir test belirsizlikleri gidermelidir.
ata 11:11

0

bu size yardımcı olabilir

[oracle@rac1 ~]$ which bash
/bin/bash
[oracle@rac1 ~]$ cat test1.sh
if [ `id -u` != 0 ]
then
echo "Must be root to run the script
 "
exit
fi

3
Bu zaten cevaplanmış ve kabul edilmiştir. Ayrıca, cevabınız zaten gönderilmiş olanla aynı.
maulinglawns

@maulinglawns, bu cevap, diğerlerinin aksine, Bourne benzeri mermilerin hepsine taşınabilir olma haklarına sahiptir (hata stderr'de çıktıysa daha iyi olurdu, çıkış durumu sıfır olmasaydı ve komut yerine koyuldu. )
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.