การเปลี่ยนเส้นทางเอาต์พุตโปรแกรม


11

เมื่อพยายามเปลี่ยนเส้นทางผลลัพธ์ของโปรแกรมโดยใช้ "ตัวเลขบางส่วนที่มากกว่า" ไวยากรณ์ (เช่นfoo 2> myfile) ตัวเลขที่เป็นไปได้ที่นี่คืออะไรและเป็นตัวแทนของอะไร

ผมเชื่อว่า 1 /dev/stdout, /dev/stderr2 แล้ว 5 และ 6 ล่ะ มี 3, 4 หรือจำนวนมากกว่า 6?


คำตอบ:


11

โปรแกรมนี้ควรจะเขียนไปยังหมายเลขอธิบายไฟล์ที่คุณระบุ พิจารณาโปรแกรม 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
Andrew Henle

นั่นไม่ใช่ประเด็นหลักของคำถามนอกจากนี้ยังมีการส่งคืนสำหรับฟังก์ชัน printf
Archemar

การไม่ใช้ค่าที่ส่งคืนจะต่างจากการใช้ชนิดที่ไม่ถูกต้องทั้งหมด
Andrew Henle

แก้ไขฉันไม่เห็นการเปลี่ยนแปลงใน tho output ...
Archemar

10

ตัวเลขแสดงถึงตัวอธิบายไฟล์ (จัดการกับไฟล์ที่ถูกเปิด)

เชลล์มักจะมี 3 ชุดโดยอัตโนมัติ

0 - stdin 1 - stdout 2 - stderr

แต่สามารถเปิดไฟล์เพิ่มเติมและเพิ่มจำนวนได้


7

ตัวเลขเหล่านี้จะอธิบายไฟล์ ดังที่คุณบันทึกไว้มีหลายอย่างที่สร้างขึ้นโดยอัตโนมัติ เมื่อไฟล์หรือสิ่งที่คล้ายไฟล์ถูกเปิดพวกเขาจะได้รับหมายเลขอื่น

หมายเลขที่ใช้ในโปรแกรมใด ๆ นั้นขึ้นอยู่กับไฟล์ที่เปิดโดยโปรแกรมนั้นหรือใช้งานเป็นอย่างอื่น ตัวอย่างเช่นหากคุณต้องการ "บันทึก" 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>และไฟล์ที่เกี่ยวข้อง


0

กระบวนการใดก็ได้รับหมายเลขจำนวนเต็มเป็นตัวให้คำอธิบายไฟล์โดยที่มีสามตัวที่สงวนไว้ใน 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ซึ่งเป็นจำนวนอธิบายไฟล์ของไฟล์ที่อ้างถึงโดยตัวแปร

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