Doğru olmadığında echo
komutun çalıştırılmasını istiyorum cat /etc/passwd | grep "sysa"
.
Neyi yanlış yapıyorum?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Doğru olmadığında echo
komutun çalıştırılmasını istiyorum cat /etc/passwd | grep "sysa"
.
Neyi yanlış yapıyorum?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Yanıtlar:
Deneyin
if ! grep -q sysa /etc/passwd ; then
grep
true
arama hedefini bulursa döner vefalse
.
Yani DEĞİL false
== true
.
if
kabuklardaki değerlendirme çok esnek olacak şekilde tasarlanmıştır ve çoğu zaman komut zincirleri gerektirmez (yazdığınız gibi).
Ayrıca, kodunuza olduğu gibi bakarak, $( ... )
cmd ikame formunu kullanımınız övülmelidir, ancak süreçten ne çıktığını düşünün. Deneyin echo $(cat /etc/passwd | grep "sysa")
ne demek istediğimi görmek için. -c
Grep (say) seçeneğini kullanarak grep ve daha sonra if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
hangi çalışır ama oldukça eski okul yapmak için bunu daha ileri alabilirsiniz .
AMA, en yeni kabuk özelliklerini (aritmetik değerlendirme) kullanabilirsiniz.
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
bu da size c-lang tabanlı karşılaştırma operatörlerini kullanma avantajı sağlar, ==,<,>,>=,<=,%
ve belki de birkaçını .
Bu durumda, Orwellophile tarafından yapılan bir yorumda, aritmetik değerlendirme daha da ayrılabilir, örneğin
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
VEYA
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Son olarak, adlı bir ödül var Useless Use of Cat (UUOC)
. :-) Bazı insanlar yukarı ve aşağı atlayacak ve gothca ağlayacak! Sadece söyleyeceğimgrep
bunun cmd satırında bir dosya adı alabileceğini neden gerekmediğinde neden ekstra süreçleri ve boru yapılarını çağırıyorsunuz? ;-)
Umarım bu yardımcı olur.
grep "^$user:" /etc/passwd
, / etc / passwd'yi yanlışlıkla aramanın daha doğru yolu olurdu - grep -v
nerede -v isterseniz aramayı tersine çevirir karışıklık önlemek için ||
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Bence basitleştirilebilir:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
veya tek bir komut satırında
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
1>&2
yapmak için ekleme yapmaya ne dersiniz ? echo
stderr
!: not found
'grep
Bu şekilde kullanırken çıkış yeniden yönlendirmesinden kaçının . -q
çıktıyı bastırır.
Neyi yanlış yapıyorum?
$(...)
çıkış durumunu değil değeri tutar , bu yüzden bu yaklaşım yanlıştır. Ancak, bu özel durumda, gerçekten işe yarıyor çünkü sysa
test ifadesinin gerçekleşmesini sağlayacak yazdırılacak. Ancak, komut if ! [ $(true) ]; then echo false; fi
her zaman yazdırılır false
çünkü true
komut stdout'a hiçbir şey yazmaz (çıkış kodu 0 olmasına rağmen). Bu yüzden yeniden ifade edilmesi gerekiyor if ! grep ...; then
.
Bir alternatif olabilir cat /etc/passwd | grep "sysa" || echo error
. Düzenleme: Alex belirttiği gibi, kedi burada işe yaramaz : grep "sysa" /etc/passwd || echo error
.
Diğer cevapları oldukça kafa karıştırıcı buldum, umarım bu birisine yardımcı olur.
Onu destekleyen Unix sistemlerinde (macOS değil):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
Bunun avantajı, kullanımda olabilecek herhangi bir dizin hizmetini (YP / NIS veya LDAP vb.) Ve yerel parola veritabanı dosyasını sorgulayabilmesidir.
Sorun, grep -q "$username" /etc/passwd
böyle bir kullanıcı olmadığında yanlış bir pozitif vereceği, ancak desenle eşleşen başka bir şeyin olması. Dosyada başka bir yerde kısmi veya tam eşleşme varsa bu olabilir.
Örneğin passwd
, dosyamda şöyle bir satır var:
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
Bu gibi şeylere geçerli bir maç provoke olur cara
ve enoc
sistemimde böyle kullanıcılar bulunmasına rağmen, vb.
Bir grep
çözümün doğru olması için, çözümün doğru şekilde ayrıştırılması gerekir./etc/passwd
dosyayı :
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... ya da :
sınırlandırılmış alanların ilkine karşı yapılan benzer bir test .
bash
bu durumda yürütülmez .
Örnek bir cevap:
Veri kaydedicilerin çevrimiçi olduğundan emin olmak için bir cron
komut dosyası her 15 dakikada bir şöyle görünür:
#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
echo "SUBJECT: SOLAR is not responding to ping" | ssmtp abc@def.com
echo "SOLAR is not responding to ping" | ssmtp 4151112222@txt.att.com
else
echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
echo "SUBJECT: OUTSIDE is not responding to ping" | ssmtp abc@def.com
echo "OUTSIDE is not responding to ping" | ssmtp 4151112222@txt.att.com
else
echo "OUTSIDE is up"
fi
#
... montajda görebileceğiniz her veri kaydedici için http://www.SDsolarBlog.com/montage adresini ziyaret edin.
FYI, &>/dev/null
komutları kullanarak hatalar dahil tüm çıktıları/dev/null
(Şartlı da gerektirir exit status
ve ping
komut)
Ayrıca FYI, cron
işlerin bir komut dosyasında root
kullanılmasına gerek olmadığı için çalıştığını unutmayın .sudo ping
cron
!
Parantez içinde olmamalı mı ? ie[ ! EXPR ]