Domanda

Ho uno script Perl in esecuzione in una scatola AIX.

Lo script tenta di aprire un file da una determinata directory e non riesce a leggere il file perché il file non dispone dell'autorizzazione di lettura, ma viene visualizzato un errore diverso che indica ioctl inappropriato per il dispositivo .

Non dovrebbe dire qualcosa come nessuna autorizzazione di lettura per il file o qualcosa di simile?

Cosa significa questo messaggio ioctl inappropriato per dispositivo ?

Come posso ripararlo?

EDIT: questo è quello che ho trovato quando ho fatto strace .

open("/local/logs/xxx/xxxxServer.log", O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, 
    0666) = 4 _llseek(4, 0, [77146], SEEK_END) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffc14f8) = -1 ENOTTY 
    (Inappropriate ioctl for  device)
È stato utile?

Soluzione

Molto probabilmente significa che non è fallito .

Quando Perl apre un file, controlla se il file è un TTY (in modo che possa rispondere all'operatore di filetest -T $ fh ) emettendo il TCGETS ioctl contro di esso. Se il file è un file normale e non un tty, lo ioctl fallisce e imposta errno su ENOTTY (valore stringa: " ioctl inappropriato per il dispositivo "). Come dice ysth, il motivo più comune per vedere un valore imprevisto in $! è controllarlo quando non è valido, ovvero ovunque altro che non immediatamente dopo un fallimento della syscall , quindi testare i codici risultato delle tue operazioni è di fondamentale importanza.

Se open in realtà ha restituito false per te e hai trovato ENOTTY in $! , considererei questo un piccolo bug (dando un valore inutile di $! ) ma sarei anche molto curioso di sapere come sia successo. L'output di codice e / o truss sarebbe elegante.

Altri suggerimenti

Errori strani come " ioctl inappropriato per il dispositivo " di solito sono il risultato del controllo di $! a un certo punto diverso da quello appena dopo una chiamata di sistema fallita. Se mostrassi il tuo codice, scommetto che qualcuno segnalerebbe rapidamente il tuo errore.

" file " in * nix i sistemi di tipo sono molto un concetto astratto.

Possono essere aree su disco organizzate da un file system, ma potrebbero anche essere una connessione di rete, un po 'di memoria condivisa, l'output del buffer da un altro processo, uno schermo o una tastiera.

Affinché perl sia davvero utile, rispecchia molto da vicino questo modello e non tratta i file emulando un nastro magnetico come fanno molti 4gl.

Quindi ha provato un "IOCTL" operazione 'apri per scrittura' su un handle di file che non consente operazioni di scrittura che sono un'operazione IOCTL inappropriata per quel dispositivo / file.

La cosa più semplice da fare è incollare un " or die "Impossibile aprire $ myfile" alla fine dell'apertura e puoi scegliere il tuo messaggio significativo.

" ioctl inappropriato per il dispositivo " è la stringa di errore per l'errore ENOTTY. Una volta veniva innescato principalmente dai tentativi di configurare le proprietà del terminale (ad esempio la modalità eco) su un descrittore di file che non era un terminale (ma, diciamo, un file normale), quindi ENOTTY. Più in generale, viene attivato quando si esegue uno ioctl su un dispositivo che non supporta tale ioctl, quindi la stringa di errore.

Per scoprire quale ioctl viene creato che fallisce e su quale descrittore di file, eseguire lo script in strace / truss. Riconoscerai ENOTTY, seguito dalla stampa effettiva del messaggio di errore. Quindi scopri quale numero di file è stato utilizzato e quale chiamata open () ha restituito quel numero di file.

Ho appena corretto questo bug perl. Vedi https://rt.perl.org/Ticket/Display.html?id= 124232

Quando spingiamo il buffer layer su PerlIO e facciamo un controllo isatty () fallito che ovviamente fallisce su tutti i file normali, ignora l'errot ENOTTY errato.

Momento Eureka!

Ho già avuto questo errore.

Hai invocato il debugger perl con qualcosa del tipo: -

perl -d yourprog.pl > log.txt

In tal caso, perl il debug tenta di eseguire una query e di ripristinare la larghezza del terminale. Quando stdout non è un terminale questo non riesce con il messaggio IOCTL.

L'alternativa sarebbe che la sessione di debug si blocchi per sempre perché non è stato visualizzato il prompt per le istruzioni.

Poiché si tratta di un errore fatale e anche abbastanza difficile da eseguire il debug, forse la correzione potrebbe essere messa da qualche parte (nella riga di comando fornita?):

export GPG_TTY=$(tty)

Da: https://github.com/keybase/keybase-issues/issues / 2798

Oggi ho riscontrato questo errore durante il tentativo di utilizzare il codice per eliminare una cartella / file che si trovano su una scatola Windoze 7 montata come condivisione su un server Centos. Ho ottenuto il icotl inappropriato per l'errore del dispositivo e ho provato tutto ciò che mi è venuto in mente. Leggi quasi tutti i post in rete relativi a questo.

Ovviamente il problema era isolato dalla condivisione Windoze montata sul server Linux. guardato alle autorizzazioni dei file nella casella Windoze e ho notato che i file avevano le autorizzazioni impostate in sola lettura.

Modificati quelli, è tornato al server Linux e tutto ha funzionato come previsto. Questa potrebbe non essere la soluzione per la maggior parte, ma speriamo che salvi qualcuno un po 'di tempo.

Ho provato il seguente codice che sembrava funzionare:

if(open(my $FILE, "<File.txt")) {
    while(<$FILE>){
    print "

Ho provato il seguente codice che sembrava funzionare:

<*>";} } else { print "File could not be opened or did not exists\n"; }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top