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

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

때로는 표준 IO 스트림 중 하나의 "동등한 경로"( stdin, stdout, ) 를 지정해야 하는 경우가 있습니다 . stderr나는 99%의 시간 동안 Linux를 사용하고 있기 때문에 /dev/기다릴 준비가 되어 있습니다 /dev/stdin. 그리고 이 "~인 것 같다옳은 일을 하라". 하지만 한편으로는 이런 정당화가 항상 불편했습니다(물론 작동하지 않을 때까지는 "작동하는 것처럼 보였기" 때문입니다). 또한 어떻게 작동하는지에 대해서도 불편합니다. 이 작업은 휴대용입니다.

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

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

  2. 보다 일반적으로, 이 동등성은 "충분"합니까?가지고 다닐 수 있는"?

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

답변1

Linux에서는 오랫동안 사용되어 왔습니다. 이것은아니요POSIX, 비록 많은 실제 쉘(AT&T ksh및 AT&T 포함 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>&2Bash에서 실행될 것이라는 것을 알고 있으므로 다음을 사용할 수 있습니다.프로세스 교체파일 이름이 필요한 명령의 경우.

관련 정보