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 sufattore 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/1non cambia e username2non 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 hellofunziona ma echo hello > /dev/stdoutfallisce.
Una soluzione alternativa sarebbe quella di creare username2un membro del gruppo tty, ma ciò darebbe il username2permesso di scrivere a qualsiasi tty, il che è probabilmente indesiderabile.
Un'altra soluzione alternativa sarebbe quella di accedere username2all'account anziché utilizzare su, in modo che /dev/stdoutpunti 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/stdoute /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/stdoute /dev/stderrsono 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/stdoutet 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 NEWSfile 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/stdoutincondizionata 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.cper 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/stdoute /dev/stderrcorrettamente. 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/stdoute /dev/stderrfunzionava correttamente. Questo problema si presenta solo quando si suaccede 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/stderrels -lL /dev/stdout /dev/stderr?