Я не думаю, что это полностью проблема Bash.
В комментарии вы сказали, что видели эту ошибку после выполнения
sudo su username2
когда залогинен как username
. Это su
вызывает проблему.
/dev/stdout
является символической ссылкой на /proc/self/fd/1
, которая является символической ссылкой, например, на /dev/pts/1
. /dev/pts/1
, который является псевдотерминалом, принадлежит и доступен для записи username
; это право собственности было предоставлено при username
входе в систему. Когда вы sudo su username2
, право собственности /dev/pts/1
не меняется и username2
не имеет разрешения на запись.
Я бы сказал, что это ошибка. по сути, /dev/stdout
должен быть псевдоним для стандартного потока вывода, но здесь мы видим ситуацию, когда echo hello
работает, но echo hello > /dev/stdout
не работает .
Одним из обходных путей может стать username2
член группы tty
, но это даст username2
разрешение писать любому tty, что, вероятно, нежелательно.
Другим обходным решением будет вход в username2
учетную запись, а не использование su
, чтобы указывать на /dev/stdout
вновь выделенный псевдотерминал, принадлежащий username2
. Это не может быть практичным.
Другой обходной путь - изменить ваши сценарии, чтобы они не ссылались на /dev/stdout
и /dev/stderr
; например, замените это:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
этим:
echo OUT
echo ERR 1>&2
Я вижу это в моей собственной системе, Ubuntu 12.04, с bash 4.2.24, хотя bash document ( info bash
) в моей системе говорит об этом /dev/stdout
и /dev/stderr
обрабатывается специально, когда используется при перенаправлениях. Но даже если bash не обрабатывает эти имена специально, они все равно должны действовать как эквиваленты для стандартных потоков ввода-вывода. (POSIX не упоминает /dev/std{in,out,err}
, поэтому может быть трудно утверждать, что это ошибка.)
Глядя на старые версии bash, документация подразумевает, что /dev/stdout
и др. Обрабатываются специально, независимо от того, существуют файлы или нет. Эта функция была представлена в bash 2.04, и NEWS
файл для этой версии гласит:
Код перенаправления теперь обрабатывает несколько имен файлов, в частности: / dev / fd / N, / dev / stdin, / dev / stdout и / dev / stderr, независимо от того, присутствуют они в файловой системе или нет.
Но если вы изучите исходный код ( redir.c
), вы увидите, что эта специальная обработка включена, только если символ HAVE_DEV_STDIN
определен (это определяется, когда bash создается из исходного кода).
Насколько я могу судить, ни одна выпущенная версия bash не сделала специальную обработку /dev/stdout
et al безусловной - если только какой-то дистрибутив не исправил ее.
Таким образом, другой обходной путь (который я не пробовал) заключается в получении исходных текстов bash , изменении, redir.c
чтобы сделать специальную /dev/*
обработку безусловной, и использовании вашей перестроенной версии, а не той, которая пришла с вашей системой. Это, вероятно, излишне, хотя.
РЕЗЮМЕ :
Ваша ОС, как у меня, не обрабатывают права собственности и право доступа /dev/stdout
и /dev/stderr
правильно. Предположительно, bash обрабатывает эти имена специально в перенаправлениях, но на самом деле это происходит только в том случае, если файлы не существуют. Это не имеет значения, если /dev/stdout
и /dev/stderr
работает правильно. Эта проблема появляется только при переходе su
на другой аккаунт или выполнении чего-либо подобного; если вы просто войдете в учетную запись, разрешения будут правильными.
ls -l /dev/stdout /dev/stderr
иls -lL /dev/stdout /dev/stderr
?