วิธีซ่อนเอาต์พุตคำสั่งใน Bash


105

ฉันต้องการทำให้สคริปต์ Bash ของฉันสวยงามยิ่งขึ้นสำหรับผู้ใช้ปลายทาง ฉันจะซ่อนเอาต์พุตได้อย่างไรเมื่อ Bash รันคำสั่ง

ตัวอย่างเช่นเมื่อ Bash ดำเนินการ

yum install nano

สิ่งต่อไปนี้จะปรากฏต่อผู้ใช้ที่ทำการ Bash:

Loaded plugins: fastestmirror
base                                                     | 3.7 kB     00:00
base/primary_db                                          | 4.4 MB     00:03
extras                                                   | 3.4 kB     00:00
extras/primary_db                                        |  18 kB     00:00
updates                                                  | 3.4 kB     00:00
updates/primary_db                                       | 3.8 MB     00:02
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package nano.x86_64 0:2.0.9-7.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package         Arch              Version                Repository       Size
================================================================================
Installing:
 nano            x86_64            2.0.9-7.el6            base            436 k

Transaction Summary
================================================================================
Install       1 Package(s)

Total download size: 436 k
Installed size: 1.5 M
Downloading Packages:
nano-2.0.9-7.el6.x86_64.rpm                              | 436 kB     00:00
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
 Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
 Package: centos-release-6-4.el6.centos.10.x86_64 (@anaconda-CentOS-201303020151.x86_64/6.4)
 From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : nano-2.0.9-7.el6.x86_64                                      1/1
  Verifying  : nano-2.0.9-7.el6.x86_64                                      1/1

Installed:
  nano.x86_64 0:2.0.9-7.el6

Complete!

ตอนนี้ฉันต้องการซ่อนสิ่งนี้จากผู้ใช้และแสดง:

    Installing nano ......

ฉันจะทำงานนี้ให้สำเร็จได้อย่างไร? ฉันจะช่วยทำให้สคริปต์เป็นมิตรกับผู้ใช้มากขึ้นอย่างแน่นอน ในกรณีที่เกิดข้อผิดพลาดควรแสดงให้ผู้ใช้เห็น

ฉันต้องการทราบวิธีแสดงข้อความเดียวกันในขณะที่กำลังดำเนินการชุดคำสั่ง


4
echo "Installing nano ......"; yum install nano &> /dev/null
user000001


คำตอบ:


253

ใช้สิ่งนี้

{
  /your/first/command
  /your/second/command
} &> /dev/null

คำอธิบาย

ในการกำจัดเอาต์พุตจากคำสั่งคุณมีสองตัวเลือก:

  • ปิดไฟล์ตัวบอกเอาต์พุตซึ่งป้องกันไม่ให้รับอินพุตอีกต่อไป มีลักษณะดังนี้:

    your_command "Is anybody listening?" >&-
    

    โดยปกติเอาต์พุตจะไปที่ file descriptor 1 (stdout) หรือ 2 (stderr) หากคุณปิด file descriptor คุณจะต้องทำเช่นนั้นสำหรับตัวอธิบายตัวเลขทุกตัวเนื่องจาก&>(ด้านล่าง) เป็นไวยากรณ์ BASH พิเศษที่ไม่สามารถใช้ร่วมกับ>&-:

    /your/first/command >&- 2>&-
    

    ระวังคำสั่ง: >&- ปิด stdoutซึ่งเป็นสิ่งที่คุณต้องการทำ &>-เปลี่ยนเส้นทาง stdout และ stderr ไปยังไฟล์ชื่อ-(ยัติภังค์) ซึ่งไม่ใช่สิ่งที่คุณต้องการทำ ในตอนแรกจะมีลักษณะเหมือนกัน แต่ไฟล์หลังจะสร้างไฟล์จรจัดในไดเรกทอรีการทำงานของคุณ ง่ายต่อการจำ: >&2เปลี่ยนเส้นทาง stdout เป็น descriptor 2 (stderr) >&3เปลี่ยนเส้นทาง stdout ไปยัง descriptor 3 และ>&-เปลี่ยนเส้นทาง stdout ไปยังทางตัน (กล่าวคือปิด stdout)

    นอกจากนี้โปรดระวังว่าคำสั่งบางคำสั่งไม่สามารถจัดการกับไฟล์ descriptor แบบปิดได้เป็นอย่างดี ("write error: Bad file descriptor") ซึ่งเป็นสาเหตุที่วิธีแก้ปัญหาที่ดีกว่าคือ ...

  • เปลี่ยนทิศทางเอาต์พุตไป/dev/nullที่ซึ่งรับเอาต์พุตทั้งหมดและไม่ทำอะไรเลย ดูเหมือนว่า:

    your_command "Hello?" > /dev/null
    

    สำหรับการเปลี่ยนทิศทางเอาต์พุตไปยังไฟล์คุณสามารถกำหนดให้ทั้ง stdout และ stderr ไปยังที่เดียวกันได้อย่างกระชับ แต่เฉพาะใน bash:

    /your/first/command &> /dev/null
    

สุดท้ายในการทำเช่นเดียวกันสำหรับคำสั่งหลายคำสั่งในครั้งเดียวให้ล้อมรอบสิ่งทั้งหมดด้วยวงเล็บปีกกา Bash ถือว่าสิ่งนี้เป็นกลุ่มของคำสั่งโดยรวมตัวอธิบายไฟล์เอาต์พุตเพื่อให้คุณสามารถเปลี่ยนเส้นทางทั้งหมดได้ในครั้งเดียว หากคุณคุ้นเคยกับ subshells โดยใช้( command1; command2; )ไวยากรณ์แทนคุณจะพบว่าวงเล็บปีกกาทำงานในลักษณะเดียวกันเกือบทุกประการยกเว้นว่าคุณไม่เกี่ยวข้องกับมันในท่อวงเล็บปีกกาจะไม่สร้าง subshell และจะอนุญาตให้คุณตั้งค่าตัวแปรภายใน

{
  /your/first/command
  /your/second/command
} &> /dev/null

ดูคู่มือ bash เกี่ยวกับการเปลี่ยนเส้นทางสำหรับรายละเอียดตัวเลือกและไวยากรณ์เพิ่มเติม


สวัสดีฉันรู้ว่ามันเป็นคำถามเก่า แต่สามารถทำได้ตามเงื่อนไขหรือไม่ เช่นฉันต้องการซ่อนผลลัพธ์ภายใต้เงื่อนไขบางประการหรือไม่? ฉันรู้ว่าฉันสามารถทำซ้ำส่วนเดียวกันภายใต้ if-else ได้ แต่มีวิธีที่ดีกว่านี้หรือไม่
Usama Zafar

@UsamaZafar ฉันจะทำเช่นนั้นโดยการตั้งค่าตัวแปร ( "พารามิเตอร์เชลล์" ) ซึ่งคุณตั้งค่าเป็น/dev/nullหรือ/dev/stdout(หรือ/path/to/a/logfile) ตามเงื่อนไขก่อนหน้านี้ในสคริปต์จากนั้นเปลี่ยนเส้นทางไปยังปลายทางนั้นโดยใช้&> $output_dest(หรืออะไรก็ตามที่คุณตั้งชื่อ) หากคุณไม่ต้องการที่จะรวม stdout และ stderr > $output_dest 2> $errors_destในกรณีที่คุณสามารถเปลี่ยนเส้นทางพวกเขาแยกกันเช่น
Jeff Bowman

36

คุณสามารถเปลี่ยนเส้นทาง stdout เป็น / dev / null

yum install nano > /dev/null

หรือคุณสามารถเปลี่ยนเส้นทางทั้ง stdout และ stderr

yum install nano &> /dev/null.

แต่ถ้าโปรแกรมมีตัวเลือกที่เงียบยิ่งดี


23

โดยปกติกระบวนการจะมีเอาต์พุตสองแบบให้กับหน้าจอ: stdout (standard out) และstderr (standard error)

ปกติข้อความที่ให้ข้อมูลไปและข้อผิดพลาดและการแจ้งเตือนไปsdoutstderr

คุณสามารถปิดstdoutคำสั่งได้โดยทำ

MyCommand >/dev/null

และปิดstderrโดยทำ:

MyCommand 2>/dev/null

หากคุณต้องการปิดทั้งสองอย่างคุณสามารถทำได้:

MyCommand 2>&1 >/dev/null

2>&1กล่าวส่ง stderr ไปยังสถานที่เดียวกับ stdout


8

/dev/nullคุณสามารถเปลี่ยนเส้นทางออกไป สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ / dev / null โปรดอ่านลิงค์นี้

คุณสามารถซ่อนเอาต์พุตของ comand ได้ด้วยวิธีต่อไปนี้:

echo -n "Installing nano ......"; yum install nano > /dev/null; echo " done."; 

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

echo -n "Installing nano ......"; yum install nano &> /dev/null; echo " done.";

ในขณะที่รหัสนี้จะไม่แสดงอะไรใน terminal /dev/nullเนื่องจากทั้งสองข้อผิดพลาดมาตรฐานและออกมาตรฐานจะถูกเปลี่ยนเส้นทางและไร้ผลที่จะทำให้


1
แบ่งปันที่ดี .... เพื่อนช่วยแสดงวิธีการส่งออกข้อความเดียวกันเพียงครั้งเดียวสำหรับชุดคำสั่ง
user2650277


4

คุณไม่ควรใช้ bash ในกรณีนี้เพื่อกำจัดเอาต์พุต Yum มีตัวเลือก-qที่ยับยั้งผลลัพธ์

คุณจะต้องการใช้อย่างแน่นอนที่สุด -y

echo "Installing nano..."
yum -y -q install nano

หากต้องการดูตัวเลือกทั้งหมดสำหรับ yum man yumใช้


ขอบคุณฉันคิดว่ายำมีตั้งแต่ apt-get ใช้ -qq เช่นกันเพื่อปราบปราม นี่เป็นประโยชน์สำหรับสิ่งที่ฉันกำลังทำ
Hyperion

0
.SILENT:

พิมพ์ ".SILENT: "ที่จุดเริ่มต้นของสคริปต์โดยไม่มีเครื่องหมายโคลอน

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