“ 2> & 1” ทำอะไรในบรรทัดคำสั่ง


59

ฉันรู้ว่ามีการ>ใช้เครื่องหมายสำหรับการเปลี่ยนเส้นทางเอาต์พุตในบรรทัดคำสั่ง แต่ฉันมีปัญหาในการค้นหาสิ่งที่อธิบายการใช้2>&1ในบรรทัดคำสั่ง ตัวอย่างเช่น:

curl http://www.google.com > /dev/null 2>&1 &

คำตอบ:


78

1หมายถึงการส่งออกมาตรฐาน (stdout) 2หมายถึงข้อผิดพลาดมาตรฐาน (stderr)

ดังนั้น2>&1บอกว่าจะส่งข้อผิดพลาดมาตรฐานไปยังที่ที่เคยส่งออกมาตรฐานจะถูกเปลี่ยนเส้นทางเช่นกัน ซึ่งเนื่องจากมันถูกส่งไป/dev/nullเป็นคล้ายกับละเว้นผลลัพธ์ใด ๆ เลย


2
มีเหตุผลที่เครื่องหมายแอมเปอร์แซนด์ปรากฏก่อนหน้า 1 แต่ไม่ใช่ก่อนหน้า 2 หรือไม่? ฉันคิดว่า & เป็นตัวละครที่สงวนไว้สำหรับการทำงานในพื้นหลัง แต่ฉันเดาว่าเฉพาะเมื่อเครื่องหมายแอมเปอร์แซนด์ปรากฏเป็นตัวอักษรยาวที่ท้ายคำสั่ง ... ?
Matt Huggins

8
เพราะ0(stdin), 1(stdout) และ2(stderr) เป็นตัวให้คำอธิบายไฟล์จริง ๆ เชลล์จำเป็นต้องมีเครื่องหมายและใส่ไว้ข้างหน้าเพื่อเปลี่ยนเส้นทาง มันทำซ้ำไฟล์ descriptor ในกรณีนี้อย่างมีประสิทธิภาพรวมสองกระแสข้อมูลเข้าด้วยกัน
Chealion

12
ลองใช้วิธีนี้ถ้าคุณมี "1" โดยไม่มีเครื่องหมายและเชลล์จะสร้างไฟล์ชื่อ "1" และเปลี่ยนเส้นทาง stderr ไปที่มัน
CarlF

1
โอเคสิ่งนี้จะใช้ได้หรือไม่ curl http://www.google.com 2>/dev/nullบรรทัดคำสั่งรู้ได้อย่างไรว่า "2" ที่นี่มีวัตถุประสงค์เพื่อหมายถึง stderr และไม่ใช่พารามิเตอร์ที่สองที่ฉันส่งไปยังคำสั่ง curl
Matt Huggins

1
@ Matt Huggins: ใช่ ที่จะส่งออกทั้งหมดจากstderrตรงไปยัง/dev/nullแทน คุณสามารถดูได้ในทางปฏิบัติโดยพยายามcurl, curl 1>/dev/nullและcurl 2>/dev/nullเพียงเพื่อให้เห็นการเปลี่ยนแปลงที่ส่งออก เครื่องหมายแอมเปอร์แซนด์อีกครั้งจำเป็นสำหรับไฟล์ descriptor ที่จะถูกเปลี่ยนเส้นทางไปเท่านั้น
Chealion

23

TL; DR

การดึงข้อมูลhttp://www.google.comในพื้นหลังและทิ้งทั้งสองและstdoutstderr

curl http://www.google.com > /dev/null 2>&1 &

เป็นเช่นเดียวกับ

curl http://www.google.com > /dev/null 2>/dev/null &

ข้อมูลพื้นฐานเกี่ยวกับ

0, 1และ2เป็นตัวแทนของไฟล์มาตรฐานอธิบายในPOSIXระบบปฏิบัติการ บ่งแฟ้มคือการอ้างอิงระบบ (พื้น) ไฟล์หรือซ็อกเก็ต

การสร้างไฟล์ descriptor ใหม่ใน C สามารถมีลักษณะดังนี้:

fd = open("data.dat", O_RDONLY)

คำสั่งระบบ Unix ส่วนใหญ่รับอินพุตและเอาต์พุตผลลัพธ์ไปยังเทอร์มินัล curlจะเรียกสิ่งที่อยู่ใน URL ที่ระบุ ( google ดอทคอม ) stdoutและแสดงผลให้

ผลการขด

การเปลี่ยนเส้นทาง

เหมือนที่คุณพูด<และ>ใช้เพื่อเปลี่ยนเส้นทางเอาต์พุตจากคำสั่งไปยังที่อื่นเช่นไฟล์

ยกตัวอย่างเช่นในls > myfiles.txt, lsได้รับเนื้อหาไดเรกทอรีปัจจุบันและ>เปลี่ยนเส้นทางการส่งออกไปยังmyfiles.txt(ถ้าไฟล์ไม่อยู่มันถูกสร้างขึ้นทับอย่างอื่น แต่คุณสามารถใช้>>แทนการ>ที่จะผนวกไปยังแฟ้มแทน) หากคุณเรียกใช้คำสั่งด้านบนคุณจะสังเกตเห็นว่าไม่มีสิ่งใดปรากฏขึ้นที่เครื่อง ซึ่งมักหมายถึงความสำเร็จในระบบ Unix เพื่อตรวจสอบสิ่งนี้cat myfiles.txtเพื่อแสดงเนื้อหาของไฟล์ไปที่หน้าจอ

> / dev / null 2> & 1

ส่วนแรก> /dev/nullเปลี่ยนเส้นทางของstdoutที่curlส่งออกไปยัง/dev/null(เพิ่มเติมในข้างหน้านี้) และ2>&1เปลี่ยนเส้นทางstderrไปที่stdout(ซึ่งเพิ่งถูกเปลี่ยนเส้นทางไป/dev/nullเพื่อให้ทุกอย่างจะถูกส่งไป/dev/null)

ด้านซ้ายของ2>&1จะบอกสิ่งที่จะเปลี่ยนเส้นทางและทางด้านขวาจะบอกคุณว่าจะไปที่ใด &ถูกนำมาใช้ในด้านสิทธิที่จะแยกแยะความแตกต่างstdout (1)หรือstderr (2)จากไฟล์ชื่อหรือ1 2ดังนั้นใน2>1ที่สุดการสร้างไฟล์ใหม่ (หากยังไม่มีอยู่) จะมีชื่อ1และถ่ายโอนข้อมูลstderrผลลัพธ์ในนั้น

/ dev / null

/dev/nullเป็นไฟล์ว่างเปล่ากลไกที่ใช้ในการทิ้งทุกอย่างที่เขียนลงไป ดังนั้น curl http://www.google.com > /dev/nullการปราบปรามcurlผลลัพธ์ของ

> / dev / null

แต่ทำไมถึงมีบางสิ่งยังคงปรากฏบนเครื่อง? นี่คือไม่ได้ curl 's ส่งออกปกติ แต่ข้อมูลที่ส่งไปstderrใช้ที่นี่เพื่อแสดงความคืบหน้าและข้อมูลการวินิจฉัยและไม่เพียง แต่ข้อผิดพลาด

curl http://www.google.com > /dev/null 2>&1จะไม่สนใจข้อมูลcurlผลลัพธ์และcurlความคืบหน้าของทั้งคู่ ผลลัพธ์ก็คือไม่มีสิ่งใดปรากฏขึ้นบนเครื่อง

ในที่สุด

&ที่สิ้นสุดเป็นวิธีที่คุณบอกเปลือกเพื่อเรียกใช้คำสั่งเป็นงานในพื้นหลัง สิ่งนี้ทำให้พรอมต์ให้กลับมาทันทีในขณะที่คำสั่งรันแบบอะซิงโครนัสเบื้องหลัง หากต้องการดูประเภทงานปัจจุบันjobsในเทอร์มินัลของคุณ หมายเหตุนี่แตกต่างจากกระบวนการที่ทำงานในระบบของคุณ หากต้องการดูประเภทเหล่านั้นtopในเทอร์มินัล

อ้างอิง


1
นี่เป็นหนึ่งในคำตอบที่ดีที่สุดในเว็บไซต์ทั้งหมดจากมุมมองของเลย์เอาต์ทำได้ดีมาก!
OmarOthman

สิ่งหนึ่งที่ฉันไม่ได้รับคือเหตุผลที่คุณต้องการส่งทุกอย่างให้/dev/nullหรือไม่ คุณไม่ต้องการผลลัพธ์curlอย่างน้อยมีประโยชน์หรือไม่?
skube

@skube Right ในกรณีนี้มันไม่ชัดเจนสำหรับฉันว่าทำไมผู้ใช้ต้องการยกเลิกทั้ง stdout และ stderr OP อาจแค่ต้องการที่จะเข้าใจความหมายของไวยากรณ์
Jorge Bucaran


0

ฉันเข้าใจดังต่อไปนี้:

หากคุณต้องการอ่านข้อมูลเอาต์พุตและข้อผิดพลาดของคำสั่งบนหน้าจอให้เขียนเพียง: curl http://www.google.com

และบางครั้งคุณต้องการบันทึกข้อมูลเอาต์พุตเป็นไฟล์แทนที่จะเป็นหน้าจอเทอร์มินัลเพื่อตรวจสอบในภายหลังจากนั้นคุณสามารถเขียน: curl http://www.google.com > logfile

แต่ด้วยวิธีนี้ข้อมูล StdErr จะถูกละเว้นเนื่องจาก>เปลี่ยนเส้นทาง StdOut ไปlogfileเท่านั้น

ดังนั้นหากคุณสนใจข้อมูลข้อผิดพลาดของคำสั่งเมื่อล้มเหลวในการดำเนินการคุณจะต้องรวม StdOut กับ StdErr โดยใช้2>&1(ซึ่งหมายถึงการพับ StdErr เป็น StdOut) ดังนั้นบรรทัดคำสั่งต่อไปนี้สามารถเขียนได้: curl http://www.google.com > logfile2> & 1

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