ฉันจะจำวิธีใช้การเปลี่ยนเส้นทางได้อย่างไร


40

ฉันรู้ว่า

  program > /dev/null 2>&1 

ทำ. มันเปลี่ยนเส้นทางการส่งออกไปยัง/dev/nullและ2>&1หมายถึงการเปลี่ยนเส้นทางการส่งออกข้อผิดพลาดในสถานที่เดียวกันที่ส่งออก

ปัญหาของฉันคือฉันต้อง google เสมอเพราะฉันไม่เคยจำได้

ดังนั้นฉันพยายาม&2>1, 1>2&, 1>&2... ฉันพยายามทุกชุดจนกว่าฉัน google มัน ...

เคล็ดลับในการจดจำได้ง่ายคืออะไร


ฉันมีปัญหาเดียวกันดังนั้นฉันทำมัน "ยาว" วิธี - program 1> /dev/null 2>/dev/nullเปลี่ยนเส้นทางทั้ง บางครั้งคุณต้องผสมstdoutและstderrรวมกันเพื่อดูว่าเกิดอะไรขึ้นเช่นเอาท์พุทจากกระบวนการคอมไพล์ที่ซับซ้อนที่ถูกเปลี่ยนเส้นทางไปยังไฟล์ ในกรณีนี้ฉันไปจบด้วย googling
ivanivan

คำตอบ:


20

เอาต์พุตดีกว่าข้อผิดพลาดจึงมาก่อน (1 vs 2)

>มีการจดชวเลขสำหรับ 'ไปที่' ด้านซ้ายเป็นสิ่งที่ฉันต้องการส่งและด้านขวาเป็นที่ที่ฉันต้องการส่ง ตั้งแต่ 'Where' เป็น (เกือบ) ไฟล์เสมอบางสิ่งบางอย่างเช่น

program > /dev/null 2>1

จะเปลี่ยนเส้นทางไปยังไฟล์ชื่อ 1 ดังนั้นเครื่องหมายและ(&)แก้ไขไฟล์เพื่ออธิบายไฟล์

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


ประโยคแรกของคุณไม่สมเหตุสมผลกับฉัน stdoutis file descriptor 1, stderrคือ 2 ดังนั้น "error" มาก่อน "output"
Warren Young

ประโยคนั้นเป็นตัวช่วยจำที่ต้องจำไฟล์ descriptor stdoutและstderrอ้างอิง
gvkv

โอเค แต่มันก็ยังดูสับสนเนื่องจากคำถามดั้งเดิมเกี่ยวกับการพยายามจดจำลำดับของตัวละครในคาถา "2> & 1"
Warren Young

9

เคล็ดลับอย่างหนึ่งคือให้จำไว้ว่า 1 = เอาต์พุตมาตรฐาน 2 = ข้อผิดพลาดมาตรฐาน ดังนั้น:

2>&1= กระแสข้อผิดพลาดมาตรฐานจะเข้าสู่กระแสออกมาตรฐาน
1>&2= ในทางกลับกัน

หากคุณเคยตั้งโปรแกรมในภาษา C เช่นเดียวกับการจดจำเครื่องหมายแอมเปอร์แซนด์ ( &) ฉันเลือกที่จะคิดว่ามันเป็นการอ้างถึง "ที่อยู่ของ" ตัวอธิบายไฟล์ที่มีอยู่เพื่อที่คุณจะไม่เปลี่ยนไฟล์เองหรือสร้างใหม่


7

การเห็นสิ่ง&ที่เป็นปมอาจช่วยได้: คิดเกี่ยวกับสิ่งที่คุณต้องการจะทำเช่นเดียวกับการเอาท์พุทของ 2, ดังนั้น2>และมัดมันเข้าด้วยกันด้วย 1 ดังนั้น2>&1


2
ฉันเพิ่งจำวลี "สองและหนึ่ง" ไม่ว่าจะช่วยในการจำของคุณเป็นวลีหรือเป็นปมการมีใครสักคนจะช่วยได้จริงๆ
ทิมเคนเนดี้

5

ที่จริงแล้วมันขึ้นอยู่กับว่าคุณใช้เชลล์อะไร โดยทั่วไปแล้ว Bash จะให้อภัยและคุณสามารถทำได้

program &> file

5

ให้เราพิจารณาตัวเลือกทั้งสามนี้:

program  2>1
program  2>1& 
program  2>&1

อันแรกส่ง stderr ไปยังชื่อไฟล์ "1": หลังจากทั้งหมด, ทุบตีคาดว่าจะเปลี่ยนเส้นทางไปยังไฟล์

ที่สองยังเปลี่ยนเส้นทางไปยังไฟล์เดียวกัน แต่ทำงานprogramในพื้นหลัง: นั่นคือสิ่งที่ต่อท้าย&ควรจะหมายถึง

สิ่งนี้ทำให้ความเป็นไปได้ที่สามเป็นเพียงสิ่งเดียวที่สมเหตุสมผลใน bash universe สำหรับการเปลี่ยนทิศทางไปยังตัวจัดการไฟล์

วิธีการจำซึ่งเป็นหนึ่งใน 0, 1, 2? คิดเกี่ยวกับการใช้คอมพิวเตอร์จากคอนโซล ก่อนอื่นคุณต้องพิมพ์บางอย่าง (0 = stdin) จากนั้นคุณจะเห็นผลลัพธ์ (1 = stdout) ท้ายสุดและเฉพาะเมื่อมีบางอย่างผิดปกติคุณจะเห็น stderr (2)


1

วาดในวอลล์เปเปอร์ของคุณ

ตอนนี้อย่างจริงจังสิ่งนี้และสิ่งพื้นฐานอื่น ๆ ที่ฉันลืมไปเรื่อย ๆ ดังนั้นฉันจึงเพิ่มเมนูเคล็ดลับสั้น ๆ ให้กับแอพที่ฉันพัฒนาขึ้นและใช้ทุกวัน คุณอาจต้องการลองหรือใช้งานบางอย่างเช่น gnote เพื่อจดบันทึก


1

ในเรื่องที่เกี่ยวกับ bash shell ฉันพบว่าวิธีที่ดีที่สุดที่จะจำได้คือการทำความเข้าใจกับสิ่งที่เกิดขึ้น
หากสิ่งที่คุณต้องการทำคือจดจำวิธีการรับคำสั่งที่ถูกต้องคุณอาจลอง

program > /results 2> /results

นั่นเป็นสิ่งที่ดีและชัดเจนว่าเกิดอะไรขึ้นและจดจำได้ง่าย กล่าวคือ

  • 1 STDOUT กำลังจะไป /results
  • 2STDERR ก็จะตรงไปที่/results

ปัญหาคือสิ่งนี้ไม่ทำงานอย่างที่คุณคาดหวัง พิจารณาสิ่งต่อไปนี้:

ไฟล์: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

และเรียกใช้คำสั่ง

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

แล้วก็

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

เกิดอะไรขึ้นที่นี่?
ความเข้าใจของฉันคือการทุบตีการตั้งค่าการเปลี่ยนเส้นทางชี้ STDERR ไปยังไฟล์โดยตรง/tmp/resultsและเนื่องจากลักษณะ>ที่ทำ 2 สิ่ง

  1. โดยปกติแล้วจะสร้างไฟล์ใหม่ - ในกรณีนี้โอกาสผ่านไปแล้วเนื่องจากทุบตีย้ายไปที่รูทีนนี้ในเวลาที่สร้างเอาต์พุต
  2. แทรกตรงไปที่จุดเริ่มต้นของไฟล์ และไม่ได้ผนวกเช่น>>นั้น

ดังนั้นในกรณีนี้ STDERR แทรกโดยตรงในจุดเริ่มต้นของการ/tmp/resultsเอาชนะเอาท์พุทของ STDOUT
หมายเหตุ: หากคุณเคย>>ต่อท้ายคุณอาจไม่อยู่กับไวยากรณ์นี้
อย่างไรก็ตามเพื่อแก้ไขปัญหาที่คุณต้องการไม่ใช่เพื่อเปลี่ยนเส้นทาง STDERR ไปยังไฟล์โดยตรง แต่ควรรวมเอาท์พุทของ STDERR เข้าในสตรีม STDOUT ดังนั้นคุณจะไม่ได้รับการชนกัน
การใช้ตัวดำเนิน2>&1การนั้นทำได้

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

&ช่วยทุบตีจะแยกแยะออกจากไฟล์ชื่อ 1และ1อธิบายไฟล์
สำหรับฉันคำสั่ง2>&1นั้นอธิบายอย่างชัดเจนว่าเกิดอะไรขึ้น - STDERR ถูกเปลี่ยนเส้นทางที่ STDOUT ตัวเอง - และจบลงด้วย/tmp/resultsเพราะนั่นคือที่ STDOUT ชี้ (เกือบเป็นผลข้างเคียง)
ตรงข้ามกับคำแนะนำจำนวนมากที่อ้างว่าเป็นสิ่งที่2>&1ส่ง STDERR ไปยังจุดที่ STDOUT เคยชี้ไป หากเป็นจริง - คุณจะยังคงมีปัญหาการเขียนทับ

ดูข้อมูลเพิ่มเติมได้ที่ - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

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