ฉันต้องการให้echo
คำสั่งดำเนินการเมื่อcat /etc/passwd | grep "sysa"
ไม่เป็นความจริง
ผมทำอะไรผิดหรือเปล่า?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
ฉันต้องการให้echo
คำสั่งดำเนินการเมื่อcat /etc/passwd | grep "sysa"
ไม่เป็นความจริง
ผมทำอะไรผิดหรือเปล่า?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
คำตอบ:
ลอง
if ! grep -q sysa /etc/passwd ; then
grep
ส่งคืนtrue
หากพบเป้าหมายการค้นหาและfalse
หากไม่ปรากฏ
ดังนั้นอย่าfalse
==true
if
การประเมินผลในเชลล์ได้รับการออกแบบให้มีความยืดหยุ่นมากและหลายครั้งไม่จำเป็นต้องมีคำสั่ง (เช่นที่คุณเขียน)
นอกจากนี้เมื่อดูที่รหัสของคุณการใช้$( ... )
รูปแบบของการทดแทน cmd จะต้องได้รับการยกย่อง แต่ให้คิดถึงสิ่งที่เกิดขึ้นจากกระบวนการ ลองecho $(cat /etc/passwd | grep "sysa")
ดูสิ่งที่ฉันหมายถึง คุณสามารถดำเนินการต่อไปได้โดยใช้-c
ตัวเลือก (นับ) เพื่อ grep จากนั้นทำสิ่งif ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
ที่ใช้ได้ แต่เป็นโรงเรียนเก่า
แต่คุณสามารถใช้คุณสมบัติเชลล์ใหม่ล่าสุด (การประเมินทางคณิตศาสตร์) เช่น
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
ซึ่งยังช่วยให้คุณประโยชน์ของการใช้ c-lang ตามผู้ประกอบการเปรียบเทียบ==,<,>,>=,<=,%
และคนอื่น ๆ อาจจะไม่กี่
ในกรณีนี้ตามความคิดเห็นของ Orwellophile การประเมินเลขคณิตสามารถลดลงได้อีกเช่น
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
หรือ
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
ในที่สุดก็มีเป็นรางวัลUseless Use of Cat (UUOC)
ที่เรียกว่า :-) บางคนจะกระโดดขึ้นและลงและร้องไห้ gothca! ฉันจะบอกว่าgrep
สามารถใช้ชื่อไฟล์ใน cmd-line ดังนั้นทำไมจึงเรียกใช้กระบวนการพิเศษและการสร้างไพพ์เมื่อคุณไม่ต้องทำ ;-)
ฉันหวังว่านี่จะช่วยได้.
grep "^$user:" /etc/passwd
จะเป็นวิธีที่ถูกต้องมากขึ้นในการค้นหา / etc / passwd โดยบังเอิญ - grep -v
ที่-vสลับการค้นหาถ้าคุณต้องการ เพื่อหลีกเลี่ยงความยุ่งเหยิงของ ||
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
ฉันคิดว่ามันง่ายลงใน:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
หรือในบรรทัดคำสั่งเดียว
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
1>&2
ในตอนท้ายของecho
การพิมพ์ของคุณstderr
?
!: not found
'grep
ลักษณะนี้ -q
ยับยั้งเอาต์พุต
ผมทำอะไรผิดหรือเปล่า?
$(...)
เก็บค่าไม่ใช่สถานะออกนั่นคือสาเหตุที่วิธีการนี้ผิด อย่างไรก็ตามในกรณีเฉพาะนี้มันใช้งานได้จริงเพราะsysa
จะพิมพ์ออกมาซึ่งทำให้ข้อความทดสอบเป็นจริง อย่างไรก็ตามif ! [ $(true) ]; then echo false; fi
จะพิมพ์เสมอfalse
เพราะtrue
คำสั่งไม่ได้เขียนอะไรไปยัง stdout (แม้ว่ารหัสออกเป็น 0) if ! grep ...; then
นั่นคือเหตุผลที่จะต้องมีการซักค้านไป
cat /etc/passwd | grep "sysa" || echo error
ทางเลือกที่จะ เมื่ออเล็กซ์ชี้ให้เห็นแมวก็ไม่มีประโยชน์อะไรที่นี่ : grep "sysa" /etc/passwd || echo error
.
พบคำตอบอื่น ๆ ที่ค่อนข้างสับสนหวังว่านี้จะช่วยให้ใครบางคน
บนระบบ Unix ที่รองรับ (ไม่ใช่ macOS ดูเหมือน):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
นี่เป็นข้อได้เปรียบที่จะสืบค้นบริการไดเรกทอรีใด ๆ ที่อาจใช้งานอยู่ (YP / NIS หรือ LDAP เป็นต้น) และไฟล์ฐานข้อมูลรหัสผ่านท้องถิ่น
ปัญหาของgrep -q "$username" /etc/passwd
มันคือมันจะให้ผลบวกที่ผิดพลาดเมื่อไม่มีผู้ใช้ดังกล่าว แต่อย่างอื่นตรงกับรูปแบบ สิ่งนี้อาจเกิดขึ้นหากมีการจับคู่บางส่วนหรือแน่นอนที่อื่นในไฟล์
ตัวอย่างเช่นในpasswd
ไฟล์ของฉันมีเส้นบอกว่า
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
สิ่งนี้จะกระตุ้นการจับคู่ที่ถูกต้องในสิ่งที่ชอบcara
และenoc
อื่น ๆ แม้ว่าจะไม่มีผู้ใช้ในระบบของฉัน
เพื่อให้grep
วิธีการที่ถูกต้องคุณจะต้องวิเคราะห์คำ/etc/passwd
ไฟล์อย่างถูกต้อง:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... หรือการทดสอบอื่น ๆ ที่คล้ายคลึงกับ:
ฟิลด์แรกของเขตข้อมูลที่ถูก จำกัด
bash
ในกรณีนั้น
นี่คือคำตอบจากตัวอย่าง:
เพื่อให้แน่ใจว่าตัวบันทึกข้อมูลออนไลน์cron
สคริปต์ทำงานทุก ๆ 15 นาทีที่มีลักษณะดังนี้:
#!/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
#
... และอื่น ๆ สำหรับตัวบันทึกข้อมูลแต่ละตัวที่คุณสามารถดูได้ในการตัดต่อที่http://www.SDsolarBlog.com/montage
FYI โดยใช้การ&>/dev/null
เปลี่ยนเส้นทางเอาต์พุตทั้งหมดจากคำสั่งรวมถึงข้อผิดพลาดไปยัง/dev/null
(ในเงื่อนไขเท่านั้นต้องexit status
ของping
คำสั่ง)
นอกจากนี้ FYI โปรดทราบว่าตั้งแต่cron
งานรันเนื่องจากroot
ไม่จำเป็นต้องใช้sudo ping
ในcron
สคริปต์
!
จะไม่ภายในวงเล็บ? ie[ ! EXPR ]