Я не думаю, що це суто питання.
У коментарі ви сказали, що побачили цю помилку після вчинення
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
дозвіл писати на будь-які тти, що, мабуть, небажано.
Іншим вирішенням проблеми буде вхід до 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 документ ( 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
?