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