Nie sądzę, że jest to całkowicie problem bash.
W komentarzu powiedziałeś, że zobaczyłeś ten błąd po zrobieniu
sudo su username2
po zalogowaniu jako username. To właśnie supowoduje problem.
/dev/stdoutjest dowiązaniem symbolicznym do /proc/self/fd/1, które jest na przykład dowiązaniem symbolicznym /dev/pts/1. /dev/pts/1, który jest pseudoterminalem, jest własnością i jest do zapisu przez username; ta własność została przyznana po usernamezalogowaniu. Kiedy Ty sudo su username2, własność /dev/pts/1nie zmienia się i username2nie masz uprawnień do zapisu.
Twierdziłbym, że to błąd. /dev/stdout powinien być w rzeczywistości aliasem dla standardowego strumienia wyjściowego, ale tutaj widzimy sytuację, w której echo hellodziała, ale echo hello > /dev/stdoutkończy się niepowodzeniem.
Jednym z obejść byłoby utworzenie username2członka grupy tty, ale dałoby to username2pozwolenie na pisanie do dowolnego tty, co prawdopodobnie jest niepożądane.
Innym obejściem byłoby zalogowanie się na username2konto zamiast korzystania z niego su, co /dev/stdoutwskazuje na nowo przydzielony pseudoterminal, którego właścicielem jest username2. To może nie być praktyczne.
Innym obejściem byłoby zmodyfikowanie skryptów, aby nie odnosiły się do /dev/stdouti /dev/stderr; na przykład zamień to:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
przez to:
echo OUT
echo ERR 1>&2
Widzę to w moim systemie Ubuntu 12.04 z wersją bash 4.2.24 - nawet jeśli bash document ( info bash) w moim systemie to mówi /dev/stdouti /dev/stderrsą traktowane specjalnie, gdy są używane w przekierowaniach. Ale nawet jeśli bash nie traktuje tych nazw specjalnie, powinny one nadal działać jako odpowiedniki standardowych strumieni we / wy. (POSIX nie wspomina /dev/std{in,out,err}, więc może być trudno argumentować, że jest to błąd).
Patrząc na stare wersje bash, dokumentacja sugeruje, że /dev/stdoutet al są traktowani specjalnie niezależnie od tego, czy pliki istnieją, czy nie. Funkcja została wprowadzona w bash 2.04, a NEWSplik dla tej wersji mówi:
Kod przekierowania obsługuje teraz kilka nazw plików specjalnie: / dev / fd / N, / dev / stdin, / dev / stdout i / dev / stderr, niezależnie od tego, czy są one obecne w systemie plików.
Ale jeśli przyjrzysz się kodowi źródłowemu ( redir.c), zobaczysz, że ta specjalna obsługa jest włączona tylko wtedy, gdy HAVE_DEV_STDINzdefiniowany jest symbol (jest to określane, gdy bash jest budowany ze źródła).
O ile mi wiadomo, żadna wydana wersja bash nie spowodowała, że specjalne traktowanie /dev/stdoutet al jest bezwarunkowe - chyba że jakaś dystrybucja go załatała.
Tak więc innym obejściem (którego jeszcze nie próbowałem) byłoby przechwycenie źródeł bash , zmodyfikowanie redir.ctak, aby specjalna /dev/*obsługa była bezwarunkowa, i użycie zrekonstruowanej wersji zamiast tej dostarczonej z systemem. Jest to jednak prawdopodobnie przesada.
STRESZCZENIE :
System operacyjny, jak moja, nie jest obsługa własności i uprawnień /dev/stdoutoraz /dev/stderrpoprawnie. bash rzekomo traktuje te nazwy specjalnie w przekierowaniach, ale w rzeczywistości robi to tylko wtedy, gdy pliki nie istnieją. To nie ma znaczenia, czy /dev/stdouti /dev/stderrdziałało poprawnie. Ten problem pojawia się tylko wtedy, gdy przechodzisz suna inne konto lub robisz coś podobnego; jeśli po prostu zalogujesz się na konto, uprawnienia są prawidłowe.
ls -l /dev/stdout /dev/stderrils -lL /dev/stdout /dev/stderr?