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

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

stdin때때로 표준 IO 스트림( , stdout, ) 중 하나의 "동등한 경로"를 지정해야 합니다 stderr. 나는 99%의 시간을 Linux로 작업하기 때문에 /dev/get /dev/stdin등의 앞에만 추가합니다. 그리고 이것은 "것 같다그러나 우선 나는 그러한 근거에 대해 항상 불안해했습니다(물론 "작동하는 것 같으면서도 작동하지 않을 때까지"이기 때문입니다). 이 작전이 얼마나 휴대성이 좋은지.

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

  1. Linux의 맥락에서 stdin, stdout, 및 , , 및 stderr를 동일시하는 것이 안전합니까(예/아니요) ?/dev/stdin/dev/stdout/dev/stderr

  2. 보다 일반적으로, 이 동등성은 "적절하게"입니까?가지고 다닐 수 있는"?

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

답변1

선사 시대부터 Linux에서 사용할 수 있었습니다. 그것은~ 아니다POSIX, 비록 많은 실제 쉘(AT&T ksh및 을 포함 bash)이 OS에 없으면 이를 시뮬레이션합니다. 이 시뮬레이션은 쉘 수준에서만 작동합니다(예: 에 대한 명시적인 인수가 아닌 리디렉션 또는 명령줄 매개변수 open()). 즉, 다음에서 사용할 수 있어야 합니다.최대어떤 식으로든 상용 Unix 시스템(때때로 /dev/fd/N다양한 정수로 표기되지만 N이를 사용하는 대부분의 시스템은 Linux 및 *BSD처럼 심볼릭 링크를 제공합니다).

답변2

파일 /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를 가리키는 열린 파일 설명자입니다. 그 이상은 전혀 없습니다.

답변3

/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     [email protected]:/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

답변4

및 친구들 과 관련된 한 가지 문제 /dev/stdout는 특정 상황에서 친구에게 편지를 쓸 권한이 없을 수 있다는 것입니다. 예를 들어, 다음에서 스크립트를 호출할 때 이런 문제가 발생했습니다.아니야, 감옥/샌드박스/컨테이너/VM/등에서 스크립트를 실행하는 유사한 도구를 상상합니다. 비슷한 문제가 발생할 수 있습니다.

이러한 경우에 작동하는 것과 같은 구문을 사용 1>&2하고 Bash에서 실행될 것이라는 것을 알았으므로 다음을 사용할 수 있습니다.프로세스 대체파일 이름이 필요한 명령의 경우.

관련 정보