Иногда мне нужно указать «путь-эквивалент» один из стандартных IO потоков ( stdin
, stdout
, stderr
). Так как 99% времени я работаю с Linux, я просто собираюсь /dev/
получить /dev/stdin
и т. Д., И это « похоже, делает правильно». Но, с одной стороны, мне всегда было неловко по поводу такого обоснования (потому что, конечно, «это работает», пока оно не работает). Кроме того, у меня нет здравого смысла в том, насколько портативен этот маневр.
Итак, у меня есть несколько вопросов:
В контексте Linux, это безопасно (да / нет) , чтобы уравнять
stdin
,stdout
иstderr
с/dev/stdin
,/dev/stdout
и/dev/stderr
?В более общем смысле, является ли эта эквивалентность «адекватно переносимой »?
Я не мог найти ссылки на POSIX.
Ответы:
Он был доступен в Linux еще в предыстории. Это не POSIX, хотя многие фактические оболочки (включая AT & T
ksh
иbash
) будут имитировать его, если его нет в ОС; обратите внимание, что это моделирование работает только на уровне оболочки (т.е. параметр перенаправления или командной строки, а не явный аргумент, например, напримерopen()
). Тем не менее, он должен быть доступен в большинстве коммерческих систем Unix, так или иначе (иногда это пишется/dev/fd/N
для различных целых чиселN
, но большинство систем с этим будут предоставлять символические ссылки, как Linux и * BSD).источник
/dev/std{in,out,err}
они конкретно указаны как не являющиеся частью стандарта POSIX.1-2008 .ash
не поддерживает/dev/stdout
в initrd ( git.razvi.ro/… )эти
/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. В этом нет ничего более, чем это.
источник
/proc/self/fd/1
или/dev/fd/1
являются частью POSIX?/dev/std???
только символические ссылки/proc/self/fd
на Linux.POSIX 7 говорит, что они являются расширениями.
Базовые определения , раздел 2.1.1 Требования:
Найден путем поиска в POSIX HTML: где находится список функций API POSIX C?
Также довольно странно,
uuencode
инструмент дает/dev/stdout
волшебный эффект :В документации ядра Linux сказано, что все системы должны иметь ее.
https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst
Однако я не смог найти, где эти символические ссылки созданы в ядре (дистрибутив предоставлен?).
источник
/ dev / {stdout, stdin, stderr} работают в Bash на этих платформах:
Но терпит неудачу в csh на этих:
источник
bash
является особенным, поскольку он может быть скомпилирован для обработки/dev/fd/x
перенаправлений в системах, которые не имеют/dev/fd
Одна проблема с
/dev/stdout
друзьями заключается в том, что у вас может не быть разрешения писать им при определенных обстоятельствах. Например, я сталкивался с этим при вызове скриптов из Nix , и я представляю себе подобные инструменты, которые запускают скрипты в jails / sandboxes / container / VMs / etc. могут возникнуть аналогичные проблемы.Использование синтаксиса вроде
1>&2
работало в этих случаях, и, поскольку я знал, что буду работать в Bash, я мог бы использовать подстановку процессов для команд, которые ожидают имена файлов.источник