/ dev / stdin, / dev / stdout 및 / dev / stderr은 얼마나 이식성이 좋습니까?


55

때때로 나는 표준 IO 스트림 중 하나 (의 "-해당 경로의"를 지정해야 stdin, stdout, stderr). 나는 리눅스에서 작동 시간의 99 % 이후, 난 그냥 앞에 추가 /dev/얻을 /dev/stdin등, 이것은 " 보인다 옳은 일을". 그러나 한 가지 이유로, 나는 항상 그러한 이론적 근거에 대해 불안해했습니다. 또한, 나는이 기동이 얼마나 휴대 가능한지 잘 모르겠습니다.

그래서 몇 가지 질문이 있습니다.

  1. 리눅스의 맥락에서 안전합니다 (예 / 아니오) 동일시하기 위해 stdin, stdout그리고 stderr/dev/stdin, /dev/stdout그리고 /dev/stderr?

  2. 더 일반적으로,이 동등성은 "적절하게 이식성 "입니까?

POSIX 참조를 찾을 수 없습니다.



답변:


36

리눅스에서 선사 시대로 사용할 수 있습니다. 많은 실제 쉘 (AT & T 및을 포함 )이 OS에없는 경우이를 시뮬레이션합니다 (POSIX 는 아님 ). 이 시뮬레이션은 쉘 레벨에서만 작동합니다 (예 : 리디렉션 또는 명령 행 매개 변수, 예를 들어 명시 적 인수가 아님). 즉, 대부분의 상용 유닉스 시스템에서 어떤 방식 으로든 사용할 수 있어야합니다 (때로는 다양한 정수 를 사용하지만 대부분의 시스템은 Linux 및 * BSD처럼 심볼릭 링크를 제공합니다).kshbashopen()/dev/fd/NN


13
실제로 POSIX.1-2008 표준의 /dev/std{in,out,err}일부가 아닌 것으로 명시되어 있습니다.
jw013

것으로 보인다 ash지원하지 않는 /dev/stdoutinitrd를에 ( git.razvi.ro/...를 )
CMCDragonkai

@CMCDragonkai : 쉘에서 처리 할 수있는 / dev / stdout이 아니며 initrd에 대해 어떻게 생각 했습니까? 실용적으로 작게 만들기 위해 대부분의 도시가 빠져 있습니다.
Joshua

22

/dev/std{in,out,err}파일은 심볼릭 링크 보통이다 /proc/self/fd/{0,1,2}(각각). 따라서 POSIX로 정의 된 메소드를 사용하면 얻을 수있는 것이 없습니다.

POSIX를 준수하려면 출력 리디렉션을 사용하는 것이 가장 좋습니다. 쉘 출력 리디렉션은 POSIX 표준에 정의되어 있습니다 . 또한 STDIN, STDOUT, STDERR 파일 디스크립터 번호도 POSIX의 일부입니다 .
요컨대, 같은 것들이 >&2작동한다고 보장됩니다.

STDIN, STDOUT 및 STDERR의 사용법은 프로그램 시작 방법에 따라 다릅니다. 파일에 대한 열린 핸들 인 파일 디스크립터 1로 프로그램을 시작한 경우 프로그램은 파일을 승인해야합니다. 프로그램을 열어 두어야하더라도 /dev/stdout여전히 해당 파일을 가리키는 파일 설명자 1을 열면됩니다.
이것이 당신이 돌아 다니는 것이라면 TTY를 직접 열어야합니다. 일반적으로 리디렉션이 진행되지 않으면 STDIN, STDOUT 및 STDERR은 모두 동일한 TTY를 가리키는 열린 파일 디스크립터입니다. 그것보다 더 아무것도 없습니다.


2
+1, 특히 "한 가지 중요한"부분의 경우; 나는 이것을 부분적으로 소화 할 것이다 :)
Alois Mahdal

4
POSIX의 일부 인지 /proc/self/fd/1또는 /dev/fd/1일부 인지 명확히 할 수 있습니까 ?
Steven Penny

/dev/std???/proc/self/fdLinux 에서만 심볼릭 링크 입니다.
Stéphane Chazelas

5

POSIX 7은 확장이라고 말합니다.

기본 정의 , 섹션 2.1.1 요구 사항 :

시스템은 비표준 확장을 제공 할 수 있습니다. 이는 POSIX.1-2008에 필요하지 않은 기능이며 다음을 포함하지만 이에 국한되지는 않습니다.

[...]

  • 특수 속성이있는 추가 문자 특수 파일 (예  /dev/stdin:  /dev/stdout, 및  /dev/stderr)

POSIX HTML을 가져 와서 발견 : POSIX C API 함수 목록은 어디에 있습니까?

또한 이상하게 도이 uuencode도구 /dev/stdout마법의 효과를줍니다 .

decode_pathname 피연산자를 지정하면 /dev/stdout uudecode가 표준 출력을 사용해야 함을 나타냅니다.

리눅스 커널 문서는 모든 시스템이 그것을 가지고 있어야한다고 말합니다.

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst

Compulsory links
These links should exist on all systems:
/dev/fd       /proc/self/fd   symbolic   File descriptors
/dev/stdin    fd/0            symbolic   stdin file descriptor
/dev/stdout   fd/1            symbolic   stdout file descriptor
/dev/stderr   fd/2            symbolic   stderr file descriptor

그러나 커널에서 해당 심볼릭 링크가 생성 된 위치를 찾을 수 없었습니다 (distro 제공?).


1

/ dev / {stdout, stdin, stderr}는 다음 플랫폼에서 Bash에서 작동합니다.

Linux debian-ppc 3.16.0-4-powerpc #1 Debian 3.16.7-ckt25-1 (2016-03-06) ppc GNU/Linux
HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
FreeBSD freebsd.polarhome.com 10.0-RELEASE-p7 FreeBSD 10.0-RELEASE-p7 #0: Tue Jul  8 06:37:44 UTC 2014     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
Darwin macosx 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:26:45 PDT 2012; root:xnu-1699.32.7~1/RELEASE_I386 i386
GNU hurd 0.7 GNU-Mach 1.6-486/Hurd-0.7 i686-AT386 GNU
Linux mandriva.polarhome.com 2.6.33.7-desktop-2mnb #1 SMP Mon Sep 20 18:19:20 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
MirBSD miros.polarhome.com 10 Kv#10uAF-20110818 GENERIC#1330 i386
Linux pidora 3.12.23-2.20140626git25673c3.rpfr20.armv6hl.bcm2708 #1 PREEMPT Fri Jul 4 16:06:10 EDT 2014 armv6l armv6l armv6l GNU/Linux
QNX qnx 6.5.0 2010/07/09-14:44:03EDT x86pc x86
NetBSD netbsd.polarhome.com 6.1.3 NetBSD 6.1.3 (GENERIC) i386
OpenBSD openbsd.polarhome.com 4.9 GENERIC#671 i386
Linux raspbian 3.18.7+ #755 PREEMPT Thu Feb 12 17:14:31 GMT 2015 armv6l GNU/Linux
SCO_SV scosysv 5 6.0.0 i386
Linux redhat.polarhome.com 3.17.4-301.fc21.x86_64 #1 SMP Thu Nov 27 19:09:10 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
Linux suse 3.4.63-2.44-desktop #1 SMP PREEMPT Wed Oct 2 11:18:32 UTC 2013 (d91a619) x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
Linux ubuntu 3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha
Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u2 (2016-01-02) x86_64 GNU/Linux

그러나 이것에 대해 csh에서 실패합니다.

HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
Linux centos.polarhome.com 2.6.18-409.el5 #1 SMP Tue Mar 15 18:13:50 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
SCO_SV scosysv 5 6.0.0 i386
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha

6
테스트 사례는 무엇입니까? 시스템이없는 시스템의 리디렉션을 위해 자체적 bash으로 처리 할 수 ​​있도록 특별하게 구성되어 있습니다/dev/fd/x/dev/fd
Stéphane Chazelas

@ StéphaneChazelas 나는 그 설명없이 오해의 소지가 있음을 볼 수 있기 때문에 하향 조정했습니다 (Ole에 대한 위반 없음).
Evan Carroll

0

/dev/stdout친구 와의 한 가지 문제 는 특정 상황에서 그들에게 글을 쓸 수있는 권한이 없을 수 있다는 것입니다. 예를 들어 Nix 에서 스크립트를 호출 할 때이 문제가 발생 했으며 jails / sandboxes / containers / VMs / etc에서 스크립트를 실행하는 유사한 도구를 상상합니다. 비슷한 문제가 발생할 수 있습니다.

1>&2이 경우와 같은 구문을 사용하여 Bash에서 실행 중임을 알았으므로 파일 이름이 필요한 명령에 프로세스 대체 를 사용할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.