bash: / dev / stderr: autorizzazione negata


19

Dopo l'aggiornamento a una nuova versione di rilascio, i miei bashscript iniziano a sputare errori:

bash: /dev/stderr: Permission denied

nelle versioni precedenti Bash avrebbe riconosciuto internamente quei nomi di file (motivo per cui questa domanda non è un duplicato di questo ) e farebbe la cosa giusta (tm) , tuttavia, ora ha smesso di funzionare. Cosa posso fare per poter eseguire nuovamente i miei script correttamente?

Ho provato ad aggiungere l'utente che esegue lo script al gruppo tty, ma questo non fa differenza (anche dopo aver effettuato il logout e il back in).

Posso riprodurlo dalla riga di comando senza problemi:

$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release

Su un sistema precedente (Ubuntu 10.04):

$ echo $BASH_VERSION
4.1.5(1)-release

1
Qual è l'output di ls -l /dev/stdout /dev/stderre ls -lL /dev/stdout /dev/stderr?
Keith Thompson,

@Keith: vedi la mia domanda modificata. Ciò significa che Bash ha completamente abbandonato la gestione interna di questo? Sui sistemi più vecchi questi collegamenti simbolici non esistevano e tuttavia il codice funzionava senza problemi. Si noti, questo viene eseguito impersonato tramite sudo su username2 -...
0xC0000022L

Quale versione bash stai usando? echo $BASH_VERSION
jippie,

1
Quali sono le versioni vecchie e nuove (prima e dopo del tuo sistema operativo e di bash?
Keith Thompson,

Risposte:


41

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.


La proprietà del TTY dovrebbe cambiare. Questo è ciò che ConsoleKit (aka pam_ck_connector.soè per).
Mikel,

In realtà, potrei sbagliarmi. Dovrà scavare di più.
Mikel,

Sui miei sistemi, /proc/self/fd/1sta aggiornando le sue autorizzazioni, ma è inutile, dal momento che è un collegamento simbolico. Succede anche su Fedora, che sembra escludere ConsoleKit.
Mikel,

1

In realtà la ragione di ciò è che udev imposta specificatamente le autorizzazioni su 0620 su dispositivi tty e su non modifica né la proprietà né le autorizzazioni né dovrebbe. A mio avviso, ciò ci lascia in una situazione che rende / dev / std * non portatile.

La soluzione semplice è quella di mettere "mesg y" in / etc / profile (o qualunque profilo di primo livello che ti piace usare) poiché questo cambia le autorizzazioni del tuo dispositivo tty a 0622. Non mi piace molto, ma probabilmente è meglio che cambiare le regole di udev.


"msg y" non funziona
Luciano,

Aspetta ... forse la ricerca di Bash gestisce diversi nomi di file specialmente quando vengono utilizzati nei reindirizzamenti nella pagina man di Bash.
0xC0000022L

0

Come utente Linux da molto tempo ho recentemente installato un nuovo sistema Ubuntu a 64 bit 12.04 LTS ed ero sconcertato dal motivo per cui i miei script bash non funzionavano - permesso negato - e successivamente ho trovato questo thread. Ho pensato che il problema potrebbe essere dovuto a qualcosa nel nuovo sistema operativo.

Alla fine si è scoperto che avevo stupidamente usato uno strumento UI per impostare le autorizzazioni sulla mia /homedirectory e il problema era correlato all'unità . A dire il vero, ho creato una tempdirectory /opte ho scoperto che i miei script avrebbero funzionato bene da lì. Una volta riparate le /homeautorizzazioni del drive, tutto era tornato alla normalità.

Un piccolo mistero risolto. sospiro


2
Questo deve essere stato un errore diverso. La modifica di qualcosa in / home non influisce su / dev.
ott--

-1

Questa è una vecchia domanda, ma penso che sia ancora molto rilevante, quindi ecco la soluzione che ho trovato che non è menzionata qui.

Mi sono imbattuto in questa domanda poiché ho anche riscontrato problemi in un comando 'su' che eseguiva un comando come questo in bash:

echo test > /dev/stderr

Dal momento che tutto ciò che sto cercando di fare è reindirizzare stdout su stderr, quanto segue ottiene lo stesso, e funziona anche con l'account 'su' commutato:

echo test 1>&2
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.