После обновления до новой версии выпуска мои bash
скрипты начинают выдавать ошибки:
bash: /dev/stderr: Permission denied
в предыдущих версиях Bash будет внутренне признать эти имена файлов (именно поэтому этот вопрос не является дубликатом этого одного ) и сделать правильную вещь (тм) , однако, это перестало работать в настоящее время. Что я могу сделать, чтобы снова успешно запускать мои сценарии?
Я попытался добавить пользователя, запускающего сценарий, в группу tty
, но это не имеет значения (даже после выхода из системы и повторного входа).
Я могу воспроизвести это в командной строке без проблем:
$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release
В более старой системе (Ubuntu 10.04):
$ echo $BASH_VERSION
4.1.5(1)-release
bash
permissions
stdout
0xC0000022L
источник
источник
ls -l /dev/stdout /dev/stderr
иls -lL /dev/stdout /dev/stderr
?sudo su username2 -
echo $BASH_VERSION
Ответы:
Я не думаю, что это полностью проблема Bash.
В комментарии вы сказали, что видели эту ошибку после выполнения
когда залогинен как
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
; например, замените это:этим:
Я вижу это в моей собственной системе, 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
файл для этой версии гласит:Но если вы изучите исходный код (
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
на другой аккаунт или выполнении чего-либо подобного; если вы просто войдете в учетную запись, разрешения будут правильными.источник
pam_ck_connector.so
) для./proc/self/fd/1
обновляются разрешения, но это бессмысленно, так как это символическая ссылка. Бывает и на Fedora, что, похоже, исключает ConsoleKit.Фактически причина этого заключается в том, что udev специально устанавливает разрешения на 0620 для tty-устройств, и su не меняет ни владельца, ни разрешения, ни это. На мой взгляд, это оставляет нас в ситуации, которая делает / dev / std * непереносимой.
Простое решение - поместить «mesg y» в / etc / profile (или любой другой профиль верхнего уровня, который вы хотите использовать), так как это меняет права доступа вашего устройства tty на 0622. Мне это не очень нравится, но, вероятно, лучше чем изменение правил Udev.
источник
Как давний пользователь Linux, я недавно установил новую систему Ubuntu 64 bit 12.04 LTS и был озадачен тем, почему мои bash-скрипты не работали - в доступе отказано - и впоследствии я нашел этот поток. Я думал, что проблема может быть из-за чего-то в новой ОС.
В конце концов получается, что я тупо использовал инструмент пользовательского интерфейса для установки разрешений для своего
/home
каталога, и проблема была связана с диском . Чтобы быть уверенным, я создалtemp
каталог/opt
и обнаружил, что мои скрипты будут работать очень хорошо оттуда. Как только я установил/home
права доступа к диску, все вернулось к норме.Одна маленькая загадка раскрыта. вздох
источник
Это старый вопрос, но я думаю, что он все еще актуален, поэтому я нашел решение, которое здесь не упоминается.
Я столкнулся с этим вопросом, так как я также видел проблемы в коммутируемой учетной записи su, выполняющей такую команду в bash:
Так как все, что я пытаюсь сделать, это перенаправить stdout в stderr, следующее достигает того же самого, и это работает даже в переключенной учетной записи 'su':
источник