ความแตกต่างระหว่าง 2> & -, 2> / dev / null, | &, &> / dev / null และ> / dev / null 2> & 1


192

แค่มองหาความแตกต่างระหว่าง

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

และพกพาของพวกเขาด้วยnon-Bourne shellsเช่นtcsh, mkshฯลฯ


2
โปรดทราบว่าในขณะที่ mksh รองรับ&>ความเข้ากันได้ของ GNU bash ก็ไม่ควรใช้สิ่งนี้เพราะการแยกวิเคราะห์สามารถทำลายซีแมนทิกส์ของสคริปต์ POSIX ที่มีอยู่และ mksh ปิดการใช้งานในโหมด POSIX แล้ว
mirabilos

ฉันเคยเห็น^ /dev/nullสิ่งที่ทำเช่นนั้น?
balupton

คำตอบ:


241

สำหรับพื้นหลัง:

  • จำนวน 1 = ออกมาตรฐาน (เช่น STDOUT)
  • จำนวน 2 = ข้อผิดพลาดมาตรฐาน (เช่น STDERR)
  • หากตัวเลขไม่ได้ระบุอย่างชัดเจนดังนั้นจะถือว่าเป็นหมายเลข 1โดยเชลล์ (bash)

ก่อนอื่นเรามาแก้ไขการทำงานของสิ่งเหล่านี้ สำหรับการอ้างอิงดูสินค้าทุกประเภททุบตี Scripting-Guide

ฟังก์ชั่น

2>&-

รูปแบบทั่วไปของอันนี้คือM>&-โดยที่"M"เป็นหมายเลขตัวอธิบายไฟล์ นี้จะปิดการส่งออกสำหรับแล้วแต่จำนวนใดจะอธิบายไฟล์อ้างอิงคือ"M"

2>/dev/null

รูปแบบทั่วไปของอันนี้คือM>/dev/nullโดยที่"M"เป็นหมายเลขตัวอธิบายไฟล์ นี้จะเปลี่ยนเส้นทางอธิบายไฟล์, "M"/dev/nullเพื่อ

2>&1

รูปแบบทั่วไปของอันนี้คือM>&Nที่"M" & "N"เป็นหมายเลขตัวอธิบายไฟล์ มันรวมเอาท์พุทของ file descriptor "M"และ"N"ลงในสตรีมเดียว

|&

2>&1 |นี่เป็นเพียงย่อสำหรับ มันถูกเพิ่มเข้ามาใน Bash 4

&>/dev/null

>/dev/null 2>&1นี่เป็นเพียงย่อสำหรับ มันเปลี่ยนเส้นทางไฟล์อธิบาย 2 (STDERR) และให้คำอธิบายที่ 1 (STDOUT) /dev/nullเพื่อ

>/dev/null

1>/dev/nullนี่เป็นเพียงย่อสำหรับ มันเปลี่ยนเส้นทางไฟล์อธิบาย 1 (STDOUT) /dev/nullเพื่อ

พกพาไปยังที่ไม่ใช่การทุบตี, tcsh, mksh ฯลฯ

ฉันไม่ได้รับการจัดการมากด้วยเปลือกหอยอื่น ๆ นอกและcsh tcshประสบการณ์ของฉันกับทั้งสองเมื่อเทียบกับผู้ดำเนินการเปลี่ยนเส้นทางของทุบตีคือทุบตีนั้นดีกว่าในเรื่องนั้น ดูหน้า man tcshสำหรับรายละเอียดเพิ่มเติม

จากคำสั่งที่คุณถามถึงไม่มีใครได้รับการสนับสนุนโดยตรงโดย csh / tcsh คุณต้องใช้ซินแท็กซ์ต่าง ๆ เพื่อสร้างฟังก์ชั่นที่คล้ายกัน


เรามีผู้ชนะ แต่ไม่มีความแตกต่างด้านประสิทธิภาพหรือบางอย่างกับ2>&-vs 2>/dev/null(นอกเหนือจากนั้นบางโปรแกรมที่เขียนว่า "ไม่ดี" ไม่ได้2>&-ถูกตัดออกและไม่ถูกต้อง)
เดช

3
ไม่ควรมีความแตกต่างด้านประสิทธิภาพ
slm

5
&>อยู่ในbashช่วงเริ่มต้น (และหยุดการทำงานร่วมกันของ Bourne และ POSIX เนื่องจากมันหมายถึงบางสิ่งที่แตกต่างกัน >&และ|&มาจาก(t)csh(และเป็นวิธีเดียวที่จะเปลี่ยนเส้นทาง stderr) พวกเขามาzshจากจุดเริ่มต้นและเพิ่งถูกเพิ่มเข้ามาเมื่อไม่นานมาbashนี้ ดูเพิ่มเติมrcสำหรับผู้ประกอบการที่ออกแบบมาดีกว่า
Stéphane Chazelas

1
ปรับปรุง: เกี่ยวกับปัญหาประสิทธิภาพการทำงานที่ยังยืนยันที่นี่: unix.stackexchange.com/questions/163955/...
เดชอุดม

1
สวัสดี @slm ขอบคุณสำหรับการติดต่อ (+2-2=0)ฉันดีใจที่ซื้อคืนของฉันไม่ได้เปลี่ยน ตอนนี้เพื่อเป็นส่วนหนึ่งรุ่นที่ผมไม่ได้แก้ไขมาก Nแต่ในกรณีนี้ผมจะเพราะมันชี้แจงว่าข้อมูลหลังจากการดำเนินการจะเป็นที่ ฉันอ่านคำตอบของคุณและมันก็ใช้ได้ดีในทุกด้าน ความคลุมเครือเล็กน้อยนี้ทำให้ฉันคิดว่านั่นคือเหตุผลที่ฉบับ แต่ตกลงคุณสามารถเพิ่มหรือปฏิเสธใหม่ได้ตามที่คุณต้องการ ฉันหวังว่าฉันจะสามารถอธิบายประเด็นได้ ดีแล้วทำต่อไป.
ดร

11

นี่คือการเปลี่ยนเส้นทาง STDERR & STDOUT:

  • 2>/dev/null

    เปลี่ยนเส้นทาง STDERR ไปยัง / dev / null (ป้องกันไม่ให้แสดงบนคอนโซล)

  • |&

    เปลี่ยนเส้นทาง STDERR และ STDOUT เป็น STDIN ของคำสั่ง piped (cmd1 | & cmd2)

  • &>/dev/null

    เปลี่ยนเส้นทางทั้ง STDERR และ STDOUT เป็น / dev / null (ไม่มีอะไรปรากฏบนคอนโซล)

  • >/dev/null

    เปลี่ยนเส้นทาง STDOUT เป็น / dev / null (แสดงเฉพาะ STDERR บนคอนโซล)

  • 2>&-

    ใช้สำหรับปิดไฟล์ descriptor ที่ใช้กับการเปลี่ยนเส้นทาง

นี่เป็นวิธีเปลี่ยนเส้นทางมาตรฐานทั้งหมดสำหรับเชลล์เป้าหมาย


4
|&และ&>/dev/nullมีไม่ได้พกพา
Chris Down

4

ลองพิจารณาภาคผนวกนี้ของคำตอบที่เลือก คุณอาจต้องการทราบว่าฟอร์มใดเป็น POSIX และไม่ใช่รูปแบบใด

มีสองรูปแบบ POSIX ที่เกี่ยวข้อง:

2.7.2 การเปลี่ยนเส้นทางเอาต์พุต

รูปแบบทั่วไปสองรูปแบบสำหรับเอาต์พุตการเปลี่ยนทิศทางคือ:

[N]> คำ

[N]> | คำ

โดยที่ทางเลือก n แทนหมายเลขไฟล์ descriptor หากไม่ใส่ตัวเลขการเปลี่ยนเส้นทางจะหมายถึงเอาต์พุตมาตรฐาน (ตัวอธิบายไฟล์ 1)

การเปลี่ยนเส้นทางเอาต์พุตโดยใช้รูปแบบ '>' จะล้มเหลวหากตั้งค่าตัวเลือก noclobber (ดูคำอธิบายของ set -C) และไฟล์ที่ตั้งชื่อโดยการขยายตัวของคำที่มีอยู่และเป็นไฟล์ปกติ มิฉะนั้นให้เปลี่ยนเส้นทางโดยใช้ '>' หรือ "> |" รูปแบบจะทำให้ไฟล์ที่มีชื่อเป็นผลมาจากการขยายตัวของคำที่จะสร้างและเปิดสำหรับการส่งออกในการอธิบายไฟล์ที่กำหนดหรือเอาท์พุทมาตรฐานหากไม่มีการระบุ หากไฟล์ไม่มีอยู่ไฟล์นั้นจะถูกสร้างขึ้น มิฉะนั้นจะถูกตัดทอนเป็นไฟล์ว่างหลังจากเปิด

-

2.7.6 การทำซ้ำ Descriptor ไฟล์เอาต์พุต

ผู้ประกอบการเปลี่ยนเส้นทาง:

[N]> & คำ

จะทำซ้ำ descriptor ไฟล์เอาต์พุตหนึ่งอันจากอีกอันหนึ่งหรือปิดหนึ่งอัน หาก word ประเมินค่าเป็นหนึ่งหลักขึ้นไปตัวอธิบายไฟล์ที่แสดงด้วย n หรือเอาต์พุตมาตรฐานหากไม่ได้ระบุ n ให้ทำเป็นสำเนาของตัวอธิบายไฟล์ที่แสดงด้วยคำ หากตัวเลขในคำไม่ได้แสดงถึง file descriptor ที่เปิดสำหรับเอาท์พุทแล้วจะเกิดข้อผิดพลาดในการเปลี่ยนเส้นทาง ดูผลที่ตามมาของข้อผิดพลาดของเชลล์ หาก word ประเมินค่าเป็น '-' ไฟล์ descriptor n หรือเอาต์พุตมาตรฐานหากไม่ได้ระบุ n จะถูกปิด ความพยายามในการปิดไฟล์ descriptor ที่ไม่เปิดจะไม่ถือเป็นข้อผิดพลาด หากคำประเมินเป็นอย่างอื่นพฤติกรรมจะไม่ได้รับการกำหนด

ดังนั้น:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

บรรทัดสุดท้ายไม่ได้อยู่ในคำถามเดิม แต่ทำงานได้โดยไม่มีการร้องเรียนในการทุบตี (ใช้ได้กับ / dev / tty ที่ใช้แทน / dev / null)


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