การทำสำเนาเป็นส่วนสำคัญที่นี่
มาดูกันว่าไฟล์ descriptor กำลังจะไปที่ใดก่อนเปลี่ยนเส้นทาง นี่คือปกติเทอร์มินัลปัจจุบันเช่น:
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
ตอนนี้ถ้าเราเรียกโดยไม่ต้องเปลี่ยนเส้นทางการส่งออกและข้อความผิดพลาดไปที่ใต้เครื่องของฉันls -l
/dev/pts/1
หากเราเปลี่ยนเส้นทางSTDOUT
ไปยังไฟล์ ( ls -l > dirlist
) เป็นครั้งแรกจะมีลักษณะดังนี้:
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
เมื่อเราแล้วเปลี่ยนเส้นทางSTDERR
ไปยังที่ซ้ำกันของSTDOUT
's อธิบายไฟล์ ( ls -l > dirlist 2>&1
) STDERR
จะไปซ้ำกับ/home/bon/dirlist
:
STDOUT ---> /home/bon/dirlist
STDERR ---> /home/bon/dirlist
ถ้าเราจะเป็นครั้งแรกเปลี่ยนเส้นทางSTDERR
ไปซ้ำกับSTDOUT
's อธิบายไฟล์ ( ls -l 2>&1
):
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
และจากนั้น STDOUT
ไปยังแฟ้ม ( ls -l 2>&1 > dirlist
) เราจะได้รับนี้
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
ที่นี่STDERR
ยังคงไปที่สถานี
คุณจะเห็นว่าการสั่งซื้อในหน้าคนถูกต้อง
การทดสอบการเปลี่ยนเส้นทาง
ตอนนี้คุณสามารถทดสอบด้วยตัวเอง ใช้ls -l /proc/$$/fd/
คุณจะเห็นที่ไหนSTDOUT
(กับ fd 1) และSTDERR
(กับ fd 2) จะไปสำหรับกระบวนการปัจจุบัน:
$ ls -l /proc/$$/fd/
total 0
lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1
มาสร้างเชลล์สคริปต์ขนาดเล็กที่แสดงตำแหน่งตัวบ่งชี้ไฟล์ของคุณ ด้วยวิธีนี้เราจะได้รับสถานะเสมอเมื่อมีการโทรls
รวมถึงการเปลี่ยนเส้นทางจากเชลล์การโทร
$ cat > lookfd.sh
#!/bin/sh
ls -l /proc/$$/fd/
^D
$ chmod +x lookfd.sh
(ด้วยCtrlDคุณส่งสิ้นสุดไฟล์และหยุดcat
คำสั่งจากการอ่านSTDIN
)
ตอนนี้เรียกสคริปต์นี้ด้วยการเปลี่ยนเส้นทางชุดค่าผสมที่แตกต่างกัน:
$ ./lookfd.sh
total 0
lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh 2>&1 > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out 2>&1
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh
คุณสามารถเห็นได้ว่าตัวอธิบายไฟล์ 1 (สำหรับSTDOUT
) และ 2 (สำหรับSTDERR
) แตกต่างกันไป เพื่อความสนุกคุณสามารถเปลี่ยนเส้นทางSTDIN
และดูผลลัพธ์:
$ ./lookfd.sh < /dev/zero
total 0
lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh
(เหลือคำถามสำหรับผู้อ่าน: ไฟล์ descriptor 255 point อยู่ที่ไหน? ;-))