ฉันจะระงับเอาต์พุตทั้งหมดจากคำสั่งโดยใช้ Bash ได้อย่างไร


296

ฉันมีสคริปต์ Bash ที่รันโปรแกรมด้วยพารามิเตอร์ โปรแกรมนั้นแสดงสถานะบางสถานะ ไม่มีตัวเลือกใด ๆ สำหรับโปรแกรมนี้ที่จะเงียบ ฉันจะป้องกันไม่ให้สคริปต์แสดงสิ่งใดได้อย่างไร

ฉันกำลังมองหาบางสิ่งบางอย่างเช่น Windows' 'สะท้อนออก'

คำตอบ:


510

ข้อมูลต่อไปนี้ส่งเอาต์พุตมาตรฐานไปยังอุปกรณ์ null (ที่ฝากข้อมูลบิต)

scriptname >/dev/null

และถ้าคุณต้องการส่งข้อความแสดงข้อผิดพลาดให้ใช้หนึ่งในนั้น (อันแรกอาจใช้ไม่ได้ในทุกเชลล์):

scriptname &>/dev/null
scriptname >/dev/null 2>&1
scriptname >/dev/null 2>/dev/null

และหากคุณต้องการบันทึกข้อความ แต่ไม่เห็นให้แทนที่/dev/nullด้วยไฟล์จริงเช่น:

scriptname &>scriptname.out

เพื่อความสมบูรณ์ภายใต้ Windows cmd.exe (โดยที่ "nul" เทียบเท่ากับ "/ dev / null") มันคือ:

scriptname >nul 2>nul

8
โปรดทราบว่า '&>' นั้นแปลกประหลาดที่จะทุบตี (และอาจจะเป็น C เชลล์); Korn และ Bourne shell ต้องการ 2> / dev / null หรือ 2> & 1 (เพื่อส่ง stderr ไปที่เดียวกับ stdout) Korn เชลล์ดูเหมือนจะแปลความหมาย '&>' เป็น "เรียกใช้เนื้อหาถึง & ในพื้นหลังจากนั้นทำการเปลี่ยนเส้นทาง i / o ในคำสั่งว่าง"
Jonathan Leffler

2
โปรดทราบว่าคำสั่งบางคำสั่งเขียนไปยังอุปกรณ์ปลายทางโดยตรงแทนที่จะเป็นเอาต์พุต / ข้อผิดพลาดมาตรฐาน ในการทดสอบให้ใส่echo foo > $(tty)สคริปต์และเรียกใช้./test.sh &> /dev/null- เอาต์พุตยังคงถูกพิมพ์ไปยังเทอร์มินัล แน่นอนว่านี่ไม่ใช่ปัญหาหากคุณกำลังเขียนสคริปต์ที่ไม่ใช้คำสั่งดังกล่าว
l0b0

1
@ l0b0 มีวิธีทำให้ tty ของสคริปต์ (หรือโปรแกรมอื่น ๆ ) แตกต่างกันหรือไม่เพื่อให้เอาต์พุตทั้งหมดถูกเปลี่ยนเส้นทางโดยไม่คำนึงถึงตัวอย่างของคุณ? ฉันรู้ว่าหน้าจอและสคริปต์สามารถทำอะไรแบบนั้นได้ แต่ทั้งคู่นั้นพิถีพิถันและแตกต่างจาก * ระวังเป็น * ระวัง
เบรนต์

@yang /dev/nullอยู่ใน Cygwin nulคุณไม่จำเป็นต้องใช้
dimo414

47

สิ่งที่ต้องการ

script > /dev/null 2>&1

ซึ่งจะช่วยป้องกันการส่งออกมาตรฐานและ/dev/nullออกข้อผิดพลาดเปลี่ยนเส้นทางไปยังพวกเขาทั้งสอง


5
นอกจากนี้ยังประสบความสำเร็จมีเพียง> ถ้าคุณต้องการที่จะบันทึกการพิมพ์บาง;)
andynormancx

1
แม้ว่าฉันจะเพิ่มสิ่งนี้ลงในคำสั่ง gs (GhostScript) ของฉัน แต่ก็ยังพิมพ์ออกมาได้ **** คำเตือน: ไฟล์มีตัวทำเครื่องหมาย %% EOF หรือขยะหลังจาก %% EOF คำแนะนำใด ๆ?
ZurabWeb

นี้ไม่ได้เรียกใช้กระบวนการในระบบยูนิกซ์ฉันต้องทำ2>/dev/null
เปอร์

13

ลอง

: $(yourcommand)

: สั้นสำหรับ "ไม่ทำอะไรเลย"

$() เป็นเพียงคำสั่งของคุณ


3
น่าสนใจมาก แต่มีข้อ จำกัด : รหัสสถานะที่ส่งคืนจะเป็นเสมอ0(สำเร็จ) ลองดูตัวอย่างโดยใช้คำสั่งfalseที่ส่งคืน1(ล้มเหลว) เสมอ ยกตัวอย่างเช่นการแสดง( echo foo | tee file ; false ) && echo bar fooใช้เคล็ดลับของคุณเพื่อระงับการแสดงผล: ( : $(echo foo | tee file ; false) ) && echo bar. แต่มันจะแสดงbarความหมายว่ารหัสสถานะการส่งคืนคือ0(นี่ไม่ใช่รหัสสถานะที่ส่งคืนจากfalse) โปรดอัปเดตคำตอบของคุณโดยให้ข้อ จำกัด นี้ ไชโย
โอลิเบอร์

2
@olibre เกี่ยวกับDUMMY=$(yourcommand)อะไร ไม่มีข้อ จำกัด ที่คุณได้กล่าวถึง :)
semente

3
@semente Perfect: คำสั่งDUMMY=$( echo foo | tee file ; false ) && echo barไม่แสดงผลใด ๆ และคำสั่งDUMMY=$( echo foo | tee file ; true ) && echo barจะปรากฏbarขึ้น แจ้งให้เราทราบหากคุณให้คำตอบเพื่อ upvote ;-) ไชโย
olibre

9

ทางเลือกที่อาจเหมาะสมในบางสถานการณ์คือการกำหนดผลลัพธ์ของคำสั่งให้กับตัวแปร:

$ DUMMY=$( grep root /etc/passwd 2>&1 )
$ echo $?
0
$ DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
1

เนื่องจาก Bash และล่าม commandline POSIX อื่น ๆ ไม่ได้พิจารณาการกำหนดตัวแปรเป็นคำสั่งจึงมีการเคารพรหัสส่งคืนของคำสั่งปัจจุบัน

หมายเหตุ: การมอบหมายด้วยtypesetหรือdeclareคีย์เวิร์ดถือเป็นคำสั่งดังนั้นโค้ดส่งคืนที่ประเมินค่าในกรณีนี้คือการกำหนดเองและไม่ใช่คำสั่งที่เรียกใช้งานในเชลล์ย่อย:

$ declare DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
0

6

เช่นเดียวกับโพสต์ของ andynormancxให้ใช้สิ่งนี้ (หากคุณทำงานในสภาพแวดล้อม Unix):

scriptname > /dev/null

หรือคุณสามารถใช้สิ่งนี้ (หากคุณทำงานในสภาพแวดล้อม Windows):

scriptname > nul

1
คุณสามารถทำได้ดีกว่าในเชลล์ของ Windows หากคุณใช้ "scriptname> nul" แทนคุณจะไม่มีไฟล์ที่จะลบเนื่องจาก "nul" นั้นเทียบเท่ากับ / dev / null ของ Windows
andynormancx

1
@ andynormancx: นั่นคือสิ่งที่ฉันเกลียดเกี่ยวกับรูปแบบระบบไฟล์ของ Windows มันเป็นชื่อไฟล์ "สงวน" เช่น NUL, COM1, LPT1, CON และอื่น ๆ ไม่ว่าคุณจะอยู่ในไดเรกทอรีใด (แม้ว่าคุณจะอยู่ในระบบไฟล์ที่สามารถมีชื่อไฟล์เหล่านั้นได้เหมือนในเครือข่ายที่ใช้ร่วมกัน)
dreamlax

ฉันไม่คิดว่าฉันได้ใช้จริง NUL ตั้งแต่ DOS 5.x มีแฟลชฉับพลันของความทรงจำเมื่อฉันเห็นคำตอบนี้;)
andynormancx

ในกรณีที่คุณใช้งาน> nulบน Windows ที่มี cygwin หรือ git bash และตอนนี้คุณติดอยู่กับnulไฟล์ที่ไม่สามารถลบได้โปรดลองตอบคำถามนี้ดูมันใช้งานได้ดี
Daemon Painter

4

ดูตัวอย่างจากโครงการเอกสารลินุกซ์ :

3.6 ตัวอย่าง: ไฟล์ stderr และ stdout 2

สิ่งนี้จะทำทุกเอาต์พุตของโปรแกรมไปยังไฟล์ บางครั้งสิ่งนี้เหมาะสำหรับรายการ cron หากคุณต้องการให้คำสั่งส่งผ่านไปในความเงียบสนิท

     rm -f $(find / -name core) &> /dev/null 

ที่กล่าวว่าคุณสามารถใช้การเปลี่ยนเส้นทางแบบง่าย ๆ นี้:

/path/to/command &>/dev/null

1

ในสคริปต์ของคุณคุณสามารถเพิ่มสิ่งต่อไปนี้ลงในบรรทัดที่คุณรู้ว่ากำลังจะให้ผลลัพธ์:

some_code 2>>/dev/null

หรือมิฉะนั้นคุณสามารถลอง

some_code >>/dev/null

1
ไม่เคยเห็น >> ถึง / dev / null .. ออกจากความอยากรู้ .. ทำไมคุณถึงทำอย่างนี้
Florian Berndl

มันจะระงับการส่งออกทั้งหมดหรือไม่
Peter Mortensen

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