คุณสมบัติเชลล์ชื่ออะไร> (tee copyError.txt> & 2) `?


11

ฉันต้องเข้าสู่ระบบ stdout และ stderr เพื่อ logfiles แต่เพียงแสดงข้อความผิดพลาดบนหน้าจอ ฉันสามารถทำได้ด้วย:

cp -rpv a/* b 1> copyLog.txt 2> >(tee copyError.txt >&2) 

ซึ่งฉันพบที่ไหนสักแห่งในเว็บ

ฉันแค่อยากรู้ว่า>(tee copyError.txt >&2)สิ่งนี้เรียกว่าอะไร? ฉันทำไม่ได้เพราะ Google ไม่สนใจอักขระเช่นวงเล็บเหลี่ยมและวงเล็บ ..


การเปลี่ยนเส้นทางไฟล์ ( tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html )
Kartik

@terdon ฉันคิดว่า OP ระบุว่าเขาต้องการบันทึก StdOut และ StdErr ไปยังไฟล์ แต่ยังแสดง StdErr บนหน้าจอด้วย
Dmitry Avtonomov

คำตอบ:


11

จากman bash:

   Process Substitution
       Process substitution is supported  on  systems  that  support
       named  pipes  (FIFOs)  or  the  /dev/fd method of naming open
       files.  It takes the form of <(list) or >(list).  The process
       list  is  run with its input or output connected to a FIFO or
       some file in /dev/fd.  The name of this file is passed as  an
       argument  to  the current command as the result of the expan
       sion.  If the >(list) form is used, writing to the file  will
       provide  input  for  list.   If the <(list) form is used, the
       file passed as an argument should be read to obtain the  out
       put of list.

คุณสามารถค้นหา manpages ได้โดยกด/จากนั้นพิมพ์สตริงการค้นหาซึ่งเป็นวิธีที่ดีในการค้นหาข้อมูลเช่นนี้ แน่นอนว่าคุณต้องการทราบว่า manpage ใดที่จะค้นหา :)

คุณต้องอ้างถึง(แม้ว่าจะมีความหมายพิเศษเมื่อค้นหา เพื่อหาส่วนที่เกี่ยวข้องใน manpage />\(ทุบตีพิมพ์


ฉันทุบตีมากฉันก็เลยทุบคน> bashman.txt และทำให้อ่านได้อย่างเดียว ตอนนี้ฉันสามารถโหลด bashman.txt ไปที่หน้าต่างอื่นในโปรแกรมแก้ไขข้อความของฉัน (อ่านอย่างเดียว) และใช้เครื่องมืออำนวยความสะดวกทั้งหมดสำหรับการค้นหาและคัดลอกและวาง
โจ

8

>(tee copyError.txt >&2) เป็นคุณสมบัติที่แตกต่างกันเล็กน้อย:

  • >(...)เรียกว่า 'การทดแทนกระบวนการ' มันสร้างไฟล์ไปป์ที่มีชื่อ/dev/fdและการเขียนไปยังไฟล์นั้นจะให้อินพุตกับกระบวนการในวงเล็บ

  • >: โดยทั่วไปสิ่งนี้เรียกว่า 'การเปลี่ยนเส้นทางเอาต์พุต' และช่วยให้คุณส่งเอาต์พุตมาตรฐาน ( >หรือ1>) หรือข้อผิดพลาดมาตรฐาน ( 2>) ไปยังไฟล์หรือกระบวนการ >&2เป็นการเปลี่ยนเส้นทางเอาต์พุต แต่ในกรณีนี้เอาต์พุตของteeถูกส่งไปยังข้อผิดพลาดมาตรฐาน (นั่นคือสิ่งที่&2เป็น&1เอาต์พุตมาตรฐาน)

  • หากไม่มี>เครื่องหมายวงเล็บ ( ()) จะเริ่มการแบ่งย่อย การรันคำสั่งในวงเล็บจะวางไข่เชลล์อื่นซึ่งจะมีอยู่ตราบเท่าที่คำสั่งเหล่านั้นกำลังรันอยู่ คุณสามารถดูวิธีการทำงานถ้าคุณประกาศตัวแปรใน subshell:

    $ foo='Tom';(foo='Dick'; echo "Sub: $foo"); echo "Orig: $foo"
    Sub: Dick
    Orig: Tom

    อย่างที่คุณเห็น$fooนั่นคือสิ่งที่กำหนดไว้ใน subshell นั้นแยกจากสิ่งที่กำหนดไว้ใน parent parent


4
ไม่ใช่>(...)ไม่ใช่การเปลี่ยนเส้นทาง >(...)ถูกขยายเป็นชื่อไฟล์ หากคุณต้องการเปลี่ยนเส้นทางไปยังสิ่งนั้นคุณต้องใช้> >(...)แต่>(...)โดยทั่วไปจะใช้มากกว่าซึ่งไม่สามารถเปลี่ยนเส้นทางได้ คำสั่งของ OP สามารถทำได้ด้วยไพพ์ดั้งเดิมไม่จำเป็นต้องมีการทดแทนกระบวนการที่นั่น
Stéphane Chazelas

@StephaneChazelas ยินดีที่ได้เห็นวิธีแก้ปัญหาที่คุณมีอยู่ในใจ
Dmitry Avtonomov

3
@chhhcmd 2>&1 > output | tee err >&2
Stéphane Chazelas

@StephaneChazelas ขอบคุณ!
Dmitry Avtonomov

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