Non penso che questo sia interamente un problema bash.
In un commento, hai detto di aver visto questo errore dopo averlo fatto
sudo su username2
quando si accede come username
. È il su
fattore scatenante del problema.
/dev/stdout
è un link simbolico a /proc/self/fd/1
, che è un link simbolico, ad esempio, /dev/pts/1
. /dev/pts/1
, che è uno pseudoterminale, è di proprietà di e scrivibile da username
; tale proprietà è stata concessa al momento dell'accesso username
. Quando tu sudo su username2
, la proprietà di /dev/pts/1
non cambia e username2
non hai il permesso di scrivere.
Direi che questo è un bug. /dev/stdout
dovrebbe essere, in effetti, un alias per il flusso di output standard, ma qui vediamo una situazione in cui echo hello
funziona ma echo hello > /dev/stdout
fallisce.
Una soluzione alternativa sarebbe quella di creare username2
un membro del gruppo tty
, ma ciò darebbe il username2
permesso di scrivere a qualsiasi tty, il che è probabilmente indesiderabile.
Un'altra soluzione alternativa sarebbe quella di accedere username2
all'account anziché utilizzare su
, in modo che /dev/stdout
punti a uno pseudoterminale appena assegnato di proprietà username2
. Questo potrebbe non essere pratico.
Un'altra soluzione alternativa sarebbe quella di modificare i tuoi script in modo che non facciano riferimento a /dev/stdout
e /dev/stderr
; ad esempio, sostituire questo:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
da questo:
echo OUT
echo ERR 1>&2
Vedo questo sul mio sistema, Ubuntu 12.04, con bash 4.2.24 - anche se il documento bash ( info bash
) sul mio sistema lo dice /dev/stdout
e /dev/stderr
sono trattati specialmente quando usati nei reindirizzamenti. Ma anche se bash non tratta questi nomi in modo particolare, dovrebbero comunque fungere da equivalenti per i flussi I / O standard. (POSIX non menziona /dev/std{in,out,err}
, quindi potrebbe essere difficile sostenere che si tratta di un bug.)
Osservando le vecchie versioni di bash, la documentazione implica che /dev/stdout
et al sia trattato in modo speciale indipendentemente dal fatto che i file esistano o meno. La funzionalità è stata introdotta in bash 2.04 e il NEWS
file per quella versione dice:
Il codice di reindirizzamento ora gestisce diversi nomi di file appositamente: / dev / fd / N, / dev / stdin, / dev / stdout e / dev / stderr, indipendentemente dal fatto che siano presenti nel file system.
Ma se si esamina il codice sorgente ( redir.c
), si vedrà che la gestione speciale è abilitata solo se il simbolo HAVE_DEV_STDIN
è definito (questo è determinato quando bash è costruito dal sorgente).
Per quanto ne so, nessuna versione rilasciata di bash ha reso /dev/stdout
incondizionata la gestione speciale di et al - a meno che qualche distribuzione non l'abbia corretto.
Quindi un'altra soluzione alternativa (che non ho provato) sarebbe quella di afferrare i sorgenti di bash , modificarli redir.c
per rendere /dev/*
incondizionata la gestione speciale e usare la tua versione ricostruita piuttosto che quella fornita con il tuo sistema. Questo è probabilmente eccessivo, però.
SOMMARIO :
Il tuo sistema operativo, come il mio, non gestisce la proprietà e le autorizzazioni di /dev/stdout
e /dev/stderr
correttamente. bash presumibilmente tratta questi nomi specialmente nei reindirizzamenti, ma in realtà lo fa solo se i file non esistono. Questo non sarebbe un problema se /dev/stdout
e /dev/stderr
funzionava correttamente. Questo problema si presenta solo quando si su
accede a un altro account o si fa qualcosa di simile; se accedi semplicemente a un account, le autorizzazioni sono corrette.
ls -l /dev/stdout /dev/stderr
els -lL /dev/stdout /dev/stderr
?