การใช้เส้นประ (-) แทนชื่อไฟล์


110

สำหรับคำสั่งหากใช้-เป็นอาร์กิวเมนต์แทนชื่อไฟล์จะหมายถึง STDIN หรือ STDOUT

  1. แต่ในตัวอย่างนี้มันจะสร้างไฟล์ที่มีชื่อ-:

    echo hello > -

    ฉันจะทำ-ในตัวอย่างนี้หมายถึง STDOUT ได้อย่างไร

  2. ในทางกลับกันฉันจะทำให้-ชื่อไฟล์เป็น-ตัวอย่างได้อย่างไร:

    cat -

3
เนื่องจากฉันต้องมี 50 ชื่อเสียงในการแสดงความคิดเห็นโดยตรง ... ในความคิดเห็น / dev / stdin / dev / stdout, AIX, ซึ่งเป็นอนุพันธ์ของ UNIX ที่ถูกต้องตามกฎหมายจึงไม่มี pseudodevices เหล่านี้ และในฐานะที่เป็นความคิดเห็นเพิ่มเติม LINUX ไม่ได้เป็นอนุพันธ์ของยูนิกซ์ในทุกกรณี มันเป็นเวิร์คกิ้งที่สอดคล้องกับ POSIX และเป็นที่นิยมมากที่สุดของระบบปฏิบัติการ UNIX-ish ในตอนนี้ แต่อย่าทำผิดพลาดนี่ไม่ใช่ UNIX แต่ส่วนสำคัญของคำตอบที่นี่ถูกต้อง สัญกรณ์ "-" ไม่ได้แปลว่าเชลล์เป็นพิเศษและจะถูกส่งโดยตรงไปยังแต่ละแอปพลิเคชันในฐานะ ARG หากแอปพลิเคชันไม่

นอกจากนี้ยังมีสิ่ง2>&-ก่อสร้างซึ่งหมายถึง "close descriptor 2"
user3132194

@ user95873 สิ่งที่ฉันคิดว่าคุณอยากจะบอกคือในขณะที่ Linux เป็นระบบปฏิบัติการยูนิกซ์เหมือนไม่ได้ทุกระบบปฏิบัติการยูนิกซ์เหมือน (หรือจริง UNIX) เป็นลินุกซ์ ไม่ว่า Linux จะเป็นจริงหรือไม่จริง UNIX (เช่นเป็นไปตามข้อกำหนด UNIX เดี่ยว) ไม่มีความเกี่ยวข้องกับปัญหา / dev / std {เข้า, ออก, err} / dev / มาตรฐาน {ในออกผิดพลาด} จะเพิ่มคุณลักษณะไม่ได้หายไป
sasha

คำตอบ:


156

การใช้-เป็นชื่อไฟล์หมายถึง stdin / stdout เป็นแบบแผนที่โปรแกรมจำนวนมากใช้ มันไม่ใช่คุณสมบัติพิเศษของชื่อไฟล์ เคอร์เนลไม่รู้จัก-เป็นพิเศษดังนั้นการเรียกระบบใด ๆ ที่อ้างถึง-เป็นชื่อไฟล์จะใช้-ตัวอักษรเป็นชื่อไฟล์อย่างแท้จริง

ด้วยการเปลี่ยนเส้นทาง bash -ไม่ได้รับการยอมรับว่าเป็นชื่อไฟล์พิเศษดังนั้นทุบตีจะใช้ชื่อนั้นเป็นชื่อไฟล์ตามตัวอักษร

เมื่อcatเห็นสตริง-เป็นชื่อไฟล์มันจะถือว่าเป็นคำพ้องสำหรับ stdin ที่จะได้รับรอบนี้คุณจะต้องปรับเปลี่ยนสายอักขระที่เห็นในลักษณะที่ว่ามันยังหมายถึงไฟล์ที่เรียกว่าcat -วิธีปกติของการทำเช่นนี้เป็นคำนำหน้าชื่อไฟล์ที่มีเส้นทาง - หรือ./- /home/Tim/-เทคนิคนี้ยังใช้เพื่อแก้ไขปัญหาที่คล้ายกันซึ่งตัวเลือกบรรทัดคำสั่งขัดแย้งกับชื่อไฟล์ดังนั้นไฟล์ที่ถูกอ้างถึง./-eจะไม่ปรากฏเป็น-eตัวเลือกบรรทัดคำสั่งสำหรับโปรแกรมตัวอย่างเช่น


37
เป็นมูลค่าเพิ่มที่/dev/stdinและ/dev/stdoutมีอยู่ในระดับสากลและสามารถใช้แทนการ-ประชุม
jmtd

นอกจากนี้ในcatกรณีนี้การใช้การเปลี่ยนเส้นทางแทนที่จะแสดงรายการอาร์กิวเมนต์อาจช่วยได้: cat <-; อย่างไรก็ตามมันยากที่จะผสมและจับคู่กับการต่อไฟล์มากกว่าหนึ่งไฟล์ในแต่ละครั้ง
jmtd

10
@jmtd: / dev / std {in, out} ไม่สามารถใช้ได้ในระดับสากล ไม่ใช่ยูนิกซ์ทุกตัวที่มี
camh

2
น่าสนใจฉันถือว่าพวกเขาเป็นส่วนหนึ่งของ POSIX (แต่ไม่สามารถยืนยันได้) อย่างน้อยก็มีอยู่บน Linux, BSDs และ Solaris คุณช่วยยกตัวอย่าง UNIX สมัยใหม่ที่ขาดมันได้หรือไม่?
jmtd

1
@camh ไม่แน่ใจว่าคุณได้รับการแจ้งเตือนหรือไม่และนี่เป็นหัวข้อที่เก่ามาก ๆ ฉันไม่แน่ใจว่าคุณจะทำได้ แต่ฉันอยากรู้มากถ้าคุณรู้คำตอบjmtdของคำถาม? :)
หมุน

18
  1. แทนที่จะคุณสามารถใช้echo hello > -echo hello > /dev/stdout

    ในขณะที่ '-' คือการประชุมที่จะต้องมีการดำเนินการโดยโปรแกรมที่ต้องการที่จะสนับสนุนแต่ละ/dev/stdin, /dev/stdoutและ/dev/stderrมีเมื่อได้รับการสนับสนุนโดย OS (อย่างน้อย Solaris, Linux และ BSDs ทำ) เป็นอิสระจากโปรแกรมแล้วจะทำงานตามที่คุณ ตั้งใจ.


9

ในฐานะที่เป็นcamh กล่าวถึง , -เป็นเพียงการตั้งชื่อที่ใช้โดยบางโปรแกรม หากคุณต้องการอ้างถึงสตรีมเหล่านี้พร้อมกับตัวให้คำอธิบายไฟล์เชลล์จะรับรู้ว่าjiliagre นั้นถูกต้องในการที่คุณใช้ชื่อ/dev/stdinหรือ/dev/stdoutแทน ชื่อไฟล์เหล่านั้นควรทำงานได้ทุกที่ที่ชื่อไฟล์ปกติจะใช้งานได้

  1. ที่ถูกกล่าวว่าตัวอย่างแรกของคุณคือโง่ เอาต์พุตใด ๆ ที่ผู้ประกอบการเปลี่ยนเส้นทางจะถูกจับไปยังไฟล์นั้นมีอยู่ใน ON มาตรฐานเอาท์พุทดังนั้นการเปลี่ยนเส้นทางและการเขียนกลับไปที่ที่มาจากนั้นไม่มีประโยชน์ พฤติกรรมที่คุณใช้มีไปป์ไม่ใช่การเปลี่ยนเส้นทาง:

    echo hello |
  2. ในตัวอย่างที่สองของคุณคุณเพียงแค่ต้องให้สิ่งบ่งชี้ว่าคุณต้องการไฟล์ litteral ของชื่อนั้นไม่ใช่นามแฝงภายในที่มี คุณสามารถทำได้ง่ายที่สุดโดยการระบุพา ธ ไปยังไฟล์ดังนี้:

    cat ./-

6

สำหรับ 1 โปรแกรมจะต้องรองรับ คุณไม่สามารถใช้มันได้โดยพลการ สำหรับ 2 ให้เปลี่ยนเส้นทางอินพุตจาก (เช่น, cat < -)


1

วิธีการ '-' มีปัญหามากมาย ก่อนอื่นมันต้องมีการตีความตัวละคร '-' และหลาย ๆ โปรแกรมไม่ทำการตีความเช่นนั้น นอกจากนี้ยังมีบางโปรแกรมที่ตีความเครื่องหมายยัติภังค์เป็นตัวคั่นที่ทำเครื่องหมายที่ส่วนท้ายของตัวเลือกบรรทัดคำสั่ง โปรแกรมถูกเขียนขึ้นเพื่อทำงานกับอาร์กิวเมนต์ชื่อไฟล์วิธีการ '-' คือแฮ็คดี แต่อ่อนแอ

วิธีที่ดีที่สุดคือ:

$ echo hello > /dev/fd/1

/dev/stdout เป็นลิงก์สัญลักษณ์ของ /dev/fd/1


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