Saya ingin echo
perintah dieksekusi ketika cat /etc/passwd | grep "sysa"
itu tidak benar.
Apa yang saya lakukan salah?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Saya ingin echo
perintah dieksekusi ketika cat /etc/passwd | grep "sysa"
itu tidak benar.
Apa yang saya lakukan salah?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Jawaban:
mencoba
if ! grep -q sysa /etc/passwd ; then
grep
kembali true
jika ia menemukan target pencarian, dan false
jika tidak.
Jadi BUKAN false
== true
.
if
evaluasi dalam shell dirancang untuk menjadi sangat fleksibel, dan seringkali tidak memerlukan rantai perintah (seperti yang telah Anda tulis).
Juga, melihat kode Anda apa adanya, penggunaan Anda atas $( ... )
bentuk substitusi cmd harus dipuji, tetapi pikirkan tentang apa yang keluar dari proses. Coba echo $(cat /etc/passwd | grep "sysa")
lihat apa yang saya maksud. Anda dapat mengambil lebih jauh dengan menggunakan opsi -c
(menghitung) untuk menangkap dan kemudian melakukan if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
yang bekerja tetapi sekolah yang agak lama.
TETAPI, Anda bisa menggunakan fitur shell terbaru (evaluasi aritmatika) seperti
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
yang juga memberi Anda manfaat menggunakan operator perbandingan berbasis c-lang, ==,<,>,>=,<=,%
dan mungkin beberapa lainnya.
Dalam hal ini, per komentar oleh Orwellophile, evaluasi aritmatika dapat dikecilkan lebih jauh, seperti
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
ATAU
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Akhirnya, ada penghargaan yang disebut Useless Use of Cat (UUOC)
. :-) Beberapa orang akan melompat-lompat dan menangis gothca! Saya hanya akan mengatakan bahwa grep
dapat mengambil nama file pada cmd-line-nya, jadi mengapa meminta proses tambahan dan konstruksi pipa ketika Anda tidak perlu? ;-)
Saya harap ini membantu.
grep "^$user:" /etc/passwd
akan menjadi cara yang lebih benar untuk mencari / etc / passwd secara kebetulan - di grep -v
mana -v membalikkan pencarian jika Anda ingin untuk menghindari kekacauan ||
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Saya pikir itu bisa disederhanakan menjadi:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
atau dalam satu baris perintah
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
1>&2
pada akhir Anda echo
untuk mencetak stderr
?
!: not found
'grep
seperti ini. -q
menekan output.
Apa yang saya lakukan salah?
$(...)
memegang nilai , bukan status keluar, itulah sebabnya pendekatan ini salah. Namun, dalam kasus khusus ini, itu memang berhasil karena sysa
akan dicetak yang membuat pernyataan pengujian menjadi kenyataan. Namun, if ! [ $(true) ]; then echo false; fi
akan selalu mencetak false
karena true
perintah tidak menulis apa pun ke stdout (meskipun kode keluarnya 0). Itu sebabnya perlu diulang if ! grep ...; then
.
Alternatifnya adalah cat /etc/passwd | grep "sysa" || echo error
. Edit: Seperti Alex menunjukkan, kucing tidak berguna di sini : grep "sysa" /etc/passwd || echo error
.
Menemukan jawaban lain agak membingungkan, semoga ini membantu seseorang.
Pada sistem Unix yang mendukungnya (bukan macOS sepertinya):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
Ini memiliki keuntungan bahwa ia akan meminta layanan direktori apa pun yang mungkin digunakan (YP / NIS atau LDAP dll.) Dan file basis data kata sandi lokal.
Masalahnya grep -q "$username" /etc/passwd
adalah bahwa hal itu akan memberikan false positive ketika tidak ada pengguna seperti itu, tetapi sesuatu yang lain cocok dengan polanya. Ini bisa terjadi jika ada kecocokan sebagian atau tepat di tempat lain dalam file.
Misalnya, dalam passwd
file saya , ada garis yang mengatakan
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
Ini akan memicu kecocokan yang valid pada hal-hal seperti cara
dan enoc
lain - lain, meskipun tidak ada pengguna seperti itu di sistem saya.
Agar grep
solusi menjadi benar, Anda perlu mengurai /etc/passwd
file dengan benar:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... atau tes serupa lainnya terhadap yang pertama dari :
bidang -disunting.
bash
dalam kasus itu.
Inilah jawaban sebagai contoh:
Untuk memastikan data logger online, sebuah cron
skrip berjalan setiap 15 menit yang terlihat seperti ini:
#!/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
#
... dan seterusnya untuk setiap data logger yang dapat Anda lihat di montase di http://www.SDsolarBlog.com/montage
FYI, menggunakan &>/dev/null
pengalihan semua output dari perintah, termasuk kesalahan, ke/dev/null
(Bersyarat hanya membutuhkan exit status
satu ping
perintah)
Juga FYI, perhatikan bahwa karena cron
pekerjaan berjalan karena root
tidak perlu digunakan sudo ping
dalam cron
skrip.
!
tidak ada di dalam kurung? yaitu[ ! EXPR ]