/ Dev / stdin, / dev / stdout ve / dev / stderr ne kadar taşınabilir?


55

Bazen ben standart IO akışları birinin ( "eşdeğer yolunu" Bir belirtmeniz gerekir stdin, stdout, stderr). Linux ile çalıştığım zamanın% 99'undan beri, sadece /dev/almaya hazırım /dev/stdin, vs. ve bu " doğru olanı yapıyor " gibi görünüyor . Ancak, bir şey için, böyle bir gerekçe hakkında her zaman tedirgin oldum (çünkü elbette, işe yaramaz hale gelinceye kadar "iş gibi görünüyor"). Dahası, bu manevranın ne kadar taşınabilir olduğu konusunda hiçbir fikrim yok.

Bu yüzden birkaç sorum var:

  1. Linux bağlamında, güvenli olduğunu (evet / hayır) bağdaştırmaya stdin, stdoutve stderrile /dev/stdin, /dev/stdoutve /dev/stderr?

  2. Daha genel olarak, bu eşdeğerlik "yeterince taşınabilir " mi?

POSIX referansı bulamadım.



Yanıtlar:


36

Linux'ta tarih öncesi haline getirildi. Öyle değil , POSIX (AT & T dahil olmak üzere birçok gerçek kabukları, ancak kshve bashbu işletim içinde mevcut değilse de simüle edilecek); Bu simülasyonun sadece kabuk düzeyinde çalıştığını unutmayın (örn open(). , örneğin, açıkça ifade ettiği gibi, yönlendirme veya komut satırı parametresi ). Yani mevcut olmalıdır belirterek, en ticari Unix sistemleri, öyle ya da (bazen yazıldığından /dev/fd/Nçeşitli tamsayılar için N, ama bu en sistemleri Linux gibi sembolik sağlamak ve * BSD yapacak).


13
Nitekim, POSIX.1-2008 standardının bir /dev/std{in,out,err}parçası olarak özellikle listelenmiştir .
jw013

Anlaşılmaktadır ashdesteklemeyen /dev/stdoutinitrd ( git.razvi.ro/... )
CMCDragonkai

@ CMCDragonkai: Bu, kabuk tarafından idare edilebilecek bir / dev / stdout değil ve initrd'den ne beklediniz? Uygulamayı olabildiğince küçük yapmak için çoğu alanı kaçırıyor.
Joshua

22

/dev/std{in,out,err}dosyalar sadece sembolik bağı normalde /proc/self/fd/{0,1,2}(sırasıyla). Bunun gibi POSIX tanımlı yöntemler kullanarak kazanılan hiçbir şey yoktur.

POSIX uyumlu olmak istiyorsanız, bunu yapmanın en iyi yolu çıktı yönlendirmesini kullanmaktır. Kabuk çıktı yönlendirmesi POSIX standardında tanımlanmıştır . Ayrıca STDIN, STDOUT STDERR dosya tanıtıcı numaraları da bir parçası olan POSIX'deki .
Kısacası, gibi şeyler >&2çalışmak için garanti edilir.

Yine de dikkat edilmesi gereken önemli bir nokta, STDIN, STDOUT ve STDERR kullanımının programın nasıl başlatıldığına bağlı olduğudur. Program, dosya tanımlayıcı 1'in dosyaya açık bir tanıtıcı olmasıyla başlatılmışsa, programınız bunu kabul etmek zorundadır. Programı açmış olsanız bile /dev/stdout, yapacağı tek şey, hala bu dosyayı gösterecek olan dosya tanıtıcısını 1 açmak.
Eğer dolaşmaya çalıştığınız şey buysa, TTY'yi doğrudan açmanız gerekir. Normalde, herhangi bir yeniden yönlendirme yapılmadan, STDIN, STDOUT ve STDERR aynı TTY'ye işaret eden açık dosya tanımlayıcılarıdır. Bundan daha fazlası kesinlikle yoktur.


2
+1, özellikle "bir önemli şey" bölümü için; Bunu parçalara göre sindireceğim :)
Alois Mahdal

4
Eğer açıklamak Can /proc/self/fd/1veya /dev/fd/1POSIX bir parçasıdır?
Steven Penny

/dev/std???/proc/self/fdLinux'ta sadece sembolik bağlantılar vardır .
Stéphane Chazelas

5

POSIX 7, uzantı olduklarını söylüyor.

Temel Tanımlar , Bölüm 2.1.1 Gereksinimler:

Sistem standart olmayan uzantılar sağlayabilir. Bunlar POSIX.1-2008 tarafından istenmeyen özelliklerdir ve bunlarla sınırlı olmamak üzere şunları içerebilir:

[...]

  • Özel özellikleri olan ek karakter özel dosyaları (örneğin,  /dev/stdin,  /dev/stdout, ve  /dev/stderr)

POSIX HTML'sini grepping yaparak bulundu: POSIX C API işlevlerinin listesi nerede?

Ayrıca oldukça esrarlı, uuencodearacı veren /dev/stdoutsihirli bir etkiye :

Bir decode_pathname işleneni /dev/stdout belirtilmesi, uudecode'un standart çıktı kullanmak olduğunu belirtir.

Linux çekirdeği belgeleri tüm sistemlerin sahip olması gerektiğini söylüyor.

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

Bununla birlikte, bu sembolik bağların çekirdeğin neresinde yaratıldığını bulamadım (dağıtım)?


1

/ dev / {stdout, stdin, stderr} Bash'in bu platformlarda çalışması:

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

Ancak bunlar üzerinde csh başarısız olur:

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
Test durumun neydi? sahip olmayan sistemlerdeki yönlendirmeler için kendi kendine işlenmesi için bashderlenebildiğinden /dev/fd/x/dev/fd
özeldir

@ StéphaneChazelas Oysa bu açıklığa kavuşturmadan yanıltıcı olduğunu görebildiğimden (Ole'ya alınmadıkça) aldım.
Evan Carroll

0

/dev/stdoutArkadaşlarınızla ve arkadaşlarınızla ilgili bir sorun , belirli durumlarda bunlara yazma izniniz olmayabilir. Örneğin, Nix'in senaryolarını çağırırken bununla karşılaştım ve hapishane / hapishane / konteynır / VM / etc'de komut dosyaları çalıştıran benzer araçlar hayal ediyorum. benzer sorunlarla karşılaşabilirsiniz.

Bu gibi 1>&2durumlarda sözdizimi kullanmak ve Bash'de çalışacağımı bildiğimden, dosya isimleri bekleyen komutlar için işlem değiştirmeyi kullanabilirim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.