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 su
powoduje problem.
/dev/stdout
jest 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 username
zalogowaniu. Kiedy Ty sudo su username2
, własność /dev/pts/1
nie zmienia się i username2
nie 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 hello
działa, ale echo hello > /dev/stdout
kończy się niepowodzeniem.
Jednym z obejść byłoby utworzenie username2
członka grupy tty
, ale dałoby to username2
pozwolenie na pisanie do dowolnego tty, co prawdopodobnie jest niepożądane.
Innym obejściem byłoby zalogowanie się na username2
konto zamiast korzystania z niego su
, co /dev/stdout
wskazuje 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/stdout
i /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/stdout
i /dev/stderr
są 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/stdout
et al są traktowani specjalnie niezależnie od tego, czy pliki istnieją, czy nie. Funkcja została wprowadzona w bash 2.04, a NEWS
plik 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_STDIN
zdefiniowany 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/stdout
et 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.c
tak, 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/stdout
oraz /dev/stderr
poprawnie. 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/stdout
i /dev/stderr
działało poprawnie. Ten problem pojawia się tylko wtedy, gdy przechodzisz su
na inne konto lub robisz coś podobnego; jeśli po prostu zalogujesz się na konto, uprawnienia są prawidłowe.
ls -l /dev/stdout /dev/stderr
ils -lL /dev/stdout /dev/stderr
?