การใช้ grep กับ pipe และ ampersand เพื่อกรองข้อผิดพลาดจาก find


22

ฉันใช้ cygwin เพื่อค้นหาไฟล์ใน cygdrive

อย่างไรก็ตามฉันต้องระงับการอนุญาตข้อความปฏิเสธ (มิฉะนั้นผลลัพธ์ที่ซ่อนอยู่ในข้อความข้อผิดพลาด) คำสั่งดังต่อไปนี้ใช้งานได้:

find -name 'myfile.*' |& grep -v "Permission denied"

ฉันไม่เข้าใจว่าทำไมเครื่องหมายแอมเปอร์แซนด์จึงต้องใส่ลงในคำสั่งนี้คาดว่าจะใช้งานได้ แต่ก็ไม่ได้

find -name 'myfile.*' | grep -v "Permission denied"

กรุณาอธิบายความหมายของเครื่องหมายและ

คำตอบ:


24

ในระบบที่คล้าย Unix จะมีสองเส้นทางที่ไม่ได้ทำการแก้ไขจะส่งออกไปยังหน้าจอของคุณ ข้อผิดพลาดมาตรฐาน (หรือ stderr) เป็นข้อผิดพลาดที่พบมากที่สุดและเงื่อนไขข้อผิดพลาด

ในการส่งผ่านข้อความปฏิเสธสิทธิ์ใน stderr ไปยังสตรีมเอาต์พุตเดียวกันกับ "เอาต์พุตปกติ" คุณต้องรวมสองข้อความเข้าด้วยกัน ในตัวอย่างของคุณเพื่อให้คุณgrep -vใช้งานได้อย่างถูกต้องคุณรวม stdout (เอาต์พุตมาตรฐาน) และ stderr กับไวยากรณ์อาร์เคนที่คุณเห็น

จากGNU Bash manual section 3.2.2 Pipelines :

หาก|&ใช้'' ข้อผิดพลาดมาตรฐานของcommand1นอกเหนือจากเอาต์พุตมาตรฐานจะเชื่อมต่อกับอินพุตมาตรฐานของcommand2 ผ่านไพพ์ 2>&1 |มันเป็นชวเลข การเปลี่ยนทิศทางโดยนัยของข้อผิดพลาดมาตรฐานไปยังเอาต์พุตมาตรฐานถูกดำเนินการหลังจากการเปลี่ยนทิศทางใด ๆ ที่ระบุโดยคำสั่ง

นอกจากนี้ตามที่ geirha ชี้ให้เห็นถ้าคุณต้องการกำจัดเอาต์พุต stderr คุณจะต้องทำอะไรบางอย่างเช่น

find -name 'myfile.*' 2> /dev/null

หรือบางที

find -name 'myfile.*' 2> /tmp/errorlog

และโปรดทราบว่าหากคุณมีสตริงคำสั่งเช่นการfindส่งเอาต์พุตไปยังxargsคุณจะต้องใส่ไพพ์ไลน์ของคำสั่งทั้งหมดในวงเล็บเพื่อจับเอาท์พุทจากส่วนประกอบทั้งหมดของคำสั่ง เช่น,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

หากคุณออกจากวงเล็บและทำสิ่งนี้แทน -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

คุณจะยังคงเห็นสิทธิ์ที่ถูกปฏิเสธข้อผิดพลาดจากการค้นหาหรือ egrep แต่ stderr จะถูกเปลี่ยนเส้นทางสำหรับ xargs

อย่างที่คุณเห็นคุณน่าจะทิ้ง stderr หลังจากดูเนื้อหาในระหว่างการทดสอบ

โปรดทราบว่าด้วย GNU findและเท่าที่ฉันสามารถบอกได้ว่า POSIX ใด ๆ ที่findเข้ากันได้-printตัวเลือกนั้นจะเป็นนัย คุณยังคงสามารถระบุได้หากคุณต้องการ


ดูเหมือนว่าจะเป็นแค่ bash4 + wiki.bash-hackers.org/bash4#redirection
ลุค

1
@LukeExton ใช่ ในเชลล์อื่น ๆ2>&1 |อาจใช้แทน|&(กล่าวคือหนึ่งสามารถเปลี่ยนเส้นทาง stderr ไปยัง stdout อย่างชัดเจนจากนั้นไพพ์นั้นไปยังคำสั่งถัดไปในไพพ์ไลน์)
Eliah Kagan

2> >( grep filter )ยังมีประโยชน์อีกด้วย
user1133275


1

หากคุณต้องการละเว้นข้อความแสดงข้อผิดพลาดเพียงแค่เปลี่ยนเส้นทาง stderr ไปที่ / dev / null

find . -name 'myfile.*' -print 2>/dev/null

นอกจากนี้ให้พิจารณาการอ่านhttp://mywiki.wooledge.org/UsingFind

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.