เมื่อพยายามเปลี่ยนเส้นทางผลลัพธ์ของโปรแกรมโดยใช้ "ตัวเลขบางส่วนที่มากกว่า" ไวยากรณ์ (เช่นfoo 2> myfile
) ตัวเลขที่เป็นไปได้ที่นี่คืออะไรและเป็นตัวแทนของอะไร
ผมเชื่อว่า 1 /dev/stdout
, /dev/stderr
2 แล้ว 5 และ 6 ล่ะ มี 3, 4 หรือจำนวนมากกว่า 6?
เมื่อพยายามเปลี่ยนเส้นทางผลลัพธ์ของโปรแกรมโดยใช้ "ตัวเลขบางส่วนที่มากกว่า" ไวยากรณ์ (เช่นfoo 2> myfile
) ตัวเลขที่เป็นไปได้ที่นี่คืออะไรและเป็นตัวแทนของอะไร
ผมเชื่อว่า 1 /dev/stdout
, /dev/stderr
2 แล้ว 5 และ 6 ล่ะ มี 3, 4 หรือจำนวนมากกว่า 6?
คำตอบ:
โปรแกรมนี้ควรจะเขียนไปยังหมายเลขอธิบายไฟล์ที่คุณระบุ พิจารณาโปรแกรม Hello world ดังต่อไปนี้:
#include <stdio.h>
main()
{
ssize_t i = 0 ;
printf ("hello world\n") ;
i = write( 5 , "Bonjour Monde\n", 14 ) ;
printf ("%d octet dans 5\n", (int) i) ;
}
รวบรวมมัน
me@mybox:~/tmp7$ make hw
cc hw.c -o hw
ตอนนี้ใช้งานง่าย
me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5
ไม่มีไฟล์สำหรับ 5 ดังนั้นจึงไม่มีการเขียนไบต์
ลองครั้งต่อไป:
me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde
ฉันจัดการเพื่อรับผลลัพธ์ในขณะที่ระบุไฟล์และ file descriptor (เช่น5>u
)
5>foo
ในทางปฏิบัติจนกว่าคุณจะได้เขียนโปรแกรมตลกดังกล่าวข้างต้นคุณไม่น่าจะเก็บข้อมูลโดยใช้
ในเชลล์สคริปต์สร้างโดยใช้ <() มีประโยชน์มากกว่า:
diff <( cmd -par 1 ) <(cmd -par 2)
write()
ผลตอบแทนที่ได้ssize_t
int
ตัวเลขแสดงถึงตัวอธิบายไฟล์ (จัดการกับไฟล์ที่ถูกเปิด)
เชลล์มักจะมี 3 ชุดโดยอัตโนมัติ
0 - stdin 1 - stdout 2 - stderr
แต่สามารถเปิดไฟล์เพิ่มเติมและเพิ่มจำนวนได้
ตัวเลขเหล่านี้จะอธิบายไฟล์ ดังที่คุณบันทึกไว้มีหลายอย่างที่สร้างขึ้นโดยอัตโนมัติ เมื่อไฟล์หรือสิ่งที่คล้ายไฟล์ถูกเปิดพวกเขาจะได้รับหมายเลขอื่น
หมายเลขที่ใช้ในโปรแกรมใด ๆ นั้นขึ้นอยู่กับไฟล์ที่เปิดโดยโปรแกรมนั้นหรือใช้งานเป็นอย่างอื่น ตัวอย่างเช่นหากคุณต้องการ "บันทึก" stdin ปัจจุบันและเปลี่ยนเส้นทาง stdin ชั่วคราวจากที่อื่นแล้วเรียกคืนในภายหลังคุณสามารถทำสิ่งต่อไปนี้:
exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate
ดังนั้นสคริปต์นี้จะมีตัว4
อธิบายไฟล์อย่างน้อยในบางครั้ง 4 นั้นอาจเป็นอะไรก็ได้ที่ไม่ได้ใช้งาน (ดีมีข้อ จำกัด ว่ามีกี่ไฟล์ที่กระบวนการสามารถเปิดได้ แต่มีอะไรภายในขีด จำกัด นั้น)
คุณสามารถดูว่าตัวให้คำอธิบายไฟล์เปิดกระบวนการอะไรและเปิดที่ไหน/proc/<pid>/fd
บ้างโดยดูที่ นั่นแสดงตัวอธิบายไฟล์ที่เปิดทั้งหมดสำหรับกระบวนการนั้น<pid>
และไฟล์ที่เกี่ยวข้อง
กระบวนการใดก็ได้รับหมายเลขจำนวนเต็มเป็นตัวให้คำอธิบายไฟล์โดยที่มีสามตัวที่สงวนไว้ใน POSIX: 0 คือ stdin, 1 คือ stdout และ 2 คือ stderr ไฟล์เพิ่มเติมใด ๆ จะถูกกำหนดหมายเลขเพิ่มเติม คุณสามารถตรวจสอบได้อย่างง่ายดายด้วยโปรแกรมนี้บันทึกเป็นfdtest.cเพื่อให้เปิดรหัสโปรแกรมของตัวเองระหว่างรันไทม์:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int fd = open("fdtest.c", O_RDONLY);
printf("%d\n", fd);
close(fd);
return 0;
}
รวบรวมมัน
gcc fdtest.c -o fdtest
เรียกใช้:
./fdtest
ผลลัพธ์ที่คุณจะได้รับเป็นดังนี้:
3
... fd
ซึ่งเป็นจำนวนอธิบายไฟล์ของไฟล์ที่อ้างถึงโดยตัวแปร