Doğru olmadığında echokomutun ç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 echokomutun ç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
greptruearama 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. -cGrep (say) seçeneğini kullanarak grep ve daha sonra if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; thenhangi ç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 -vnerede -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>&2yapmak için ekleme yapmaya ne dersiniz ? echostderr
!: not found
'grepBu ş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ü sysatest ifadesinin gerçekleşmesini sağlayacak yazdırılacak. Ancak, komut if ! [ $(true) ]; then echo false; fiher zaman yazdırılır falseçünkü truekomut 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/passwdbö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 carave enocsistemimde 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 .
bashbu durumda yürütülmez .
Örnek bir cevap:
Veri kaydedicilerin çevrimiçi olduğundan emin olmak için bir cronkomut 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/nullkomutları kullanarak hatalar dahil tüm çıktıları/dev/null
(Şartlı da gerektirir exit statusve pingkomut)
Ayrıca FYI, cronişlerin bir komut dosyasında rootkullanılmasına gerek olmadığı için çalıştığını unutmayın .sudo pingcron
!Parantez içinde olmamalı mı ? ie[ ! EXPR ]