ฉันรู้ว่ามีการ>ใช้เครื่องหมายสำหรับการเปลี่ยนเส้นทางเอาต์พุตในบรรทัดคำสั่ง แต่ฉันมีปัญหาในการค้นหาสิ่งที่อธิบายการใช้2>&1ในบรรทัดคำสั่ง ตัวอย่างเช่น:
curl http://www.google.com > /dev/null 2>&1 &
ฉันรู้ว่ามีการ>ใช้เครื่องหมายสำหรับการเปลี่ยนเส้นทางเอาต์พุตในบรรทัดคำสั่ง แต่ฉันมีปัญหาในการค้นหาสิ่งที่อธิบายการใช้2>&1ในบรรทัดคำสั่ง ตัวอย่างเช่น:
curl http://www.google.com > /dev/null 2>&1 &
คำตอบ:
1หมายถึงการส่งออกมาตรฐาน (stdout) 2หมายถึงข้อผิดพลาดมาตรฐาน (stderr)
ดังนั้น2>&1บอกว่าจะส่งข้อผิดพลาดมาตรฐานไปยังที่ที่เคยส่งออกมาตรฐานจะถูกเปลี่ยนเส้นทางเช่นกัน ซึ่งเนื่องจากมันถูกส่งไป/dev/nullเป็นคล้ายกับละเว้นผลลัพธ์ใด ๆ เลย
0(stdin), 1(stdout) และ2(stderr) เป็นตัวให้คำอธิบายไฟล์จริง ๆ เชลล์จำเป็นต้องมีเครื่องหมายและใส่ไว้ข้างหน้าเพื่อเปลี่ยนเส้นทาง มันทำซ้ำไฟล์ descriptor ในกรณีนี้อย่างมีประสิทธิภาพรวมสองกระแสข้อมูลเข้าด้วยกัน
curl http://www.google.com 2>/dev/nullบรรทัดคำสั่งรู้ได้อย่างไรว่า "2" ที่นี่มีวัตถุประสงค์เพื่อหมายถึง stderr และไม่ใช่พารามิเตอร์ที่สองที่ฉันส่งไปยังคำสั่ง curl
stderrตรงไปยัง/dev/nullแทน คุณสามารถดูได้ในทางปฏิบัติโดยพยายามcurl, curl 1>/dev/nullและcurl 2>/dev/nullเพียงเพื่อให้เห็นการเปลี่ยนแปลงที่ส่งออก เครื่องหมายแอมเปอร์แซนด์อีกครั้งจำเป็นสำหรับไฟล์ descriptor ที่จะถูกเปลี่ยนเส้นทางไปเท่านั้น
การดึงข้อมูล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เปลี่ยนเส้นทางของ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เป็นไฟล์ว่างเปล่ากลไกที่ใช้ในการทิ้งทุกอย่างที่เขียนลงไป ดังนั้น
curl http://www.google.com > /dev/nullการปราบปรามcurlผลลัพธ์ของ

แต่ทำไมถึงมีบางสิ่งยังคงปรากฏบนเครื่อง? นี่คือไม่ได้ curl 's ส่งออกปกติ แต่ข้อมูลที่ส่งไปstderrใช้ที่นี่เพื่อแสดงความคืบหน้าและข้อมูลการวินิจฉัยและไม่เพียง แต่ข้อผิดพลาด
curl http://www.google.com > /dev/null 2>&1จะไม่สนใจข้อมูลcurlผลลัพธ์และcurlความคืบหน้าของทั้งคู่ ผลลัพธ์ก็คือไม่มีสิ่งใดปรากฏขึ้นบนเครื่อง
&ที่สิ้นสุดเป็นวิธีที่คุณบอกเปลือกเพื่อเรียกใช้คำสั่งเป็นงานในพื้นหลัง สิ่งนี้ทำให้พรอมต์ให้กลับมาทันทีในขณะที่คำสั่งรันแบบอะซิงโครนัสเบื้องหลัง หากต้องการดูประเภทงานปัจจุบันjobsในเทอร์มินัลของคุณ หมายเหตุนี่แตกต่างจากกระบวนการที่ทำงานในระบบของคุณ หากต้องการดูประเภทเหล่านั้นtopในเทอร์มินัล
/dev/nullหรือไม่ คุณไม่ต้องการผลลัพธ์curlอย่างน้อยมีประโยชน์หรือไม่?
2หมายถึง STDERR 2>&1จะส่ง STDERR ไปยังตำแหน่งเดียวกับ1(STDOUT)
ฉันเข้าใจดังต่อไปนี้:
หากคุณต้องการอ่านข้อมูลเอาต์พุตและข้อผิดพลาดของคำสั่งบนหน้าจอให้เขียนเพียง:
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