2009-10-22 7 views
41

Ich habe ein Perl-Skript in einer AIX-Box ausgeführt."Ungültige ioctl für Gerät"

Das Skript versucht, eine Datei aus einem bestimmten Verzeichnis zu öffnen, und es kann die Datei nicht lesen, weil die Datei keine Leseberechtigung hat, aber ich bekomme einen anderen Fehler, nämlich inappropriate ioctl for device.

Sollte es nicht etwas wie no read permissions for file oder etwas ähnliches sagen?

Was bedeutet diese inappropriate ioctl for device Nachricht?

Wie kann ich es beheben?

EDIT: Dies ist, was ich gefunden habe, als ich strace getan habe.

 
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) 
+0

Wenn Sie die Berechtigungen vermuten - haben Sie bereits versucht, die Leseberechtigungen für die fragliche Datei festzulegen? –

+0

Response to update: Das ist offen für schreiben/anhängen, nicht lesen, und es ist erfolgreich. – hobbs

+0

Ja, aber ioctl schlägt für dieses Dateihandle fehl. irgendeine idee warum? – someguy

Antwort

32

wahrscheinlich bedeutet es, dass die offene nicht versäumte es.

Wenn Perl eine Datei öffnet, überprüft es w Ob die Datei ein TTY ist oder nicht (so dass sie den Filetestoperator -T $fh beantworten kann), indem Sie die ioctl-Datei TCGETS dagegen ausgeben. Wenn es sich bei der Datei um eine reguläre Datei und nicht um ein tty handelt, schlägt ioctl fehl und setzt errno auf ENOTTY (Zeichenfolgenwert: "Unzutreffendes ioctl für Gerät"). Wie ysth sagt, ist der häufigste Grund, einen unerwarteten Wert in $! zu sehen, es zu überprüfen, wenn es nicht gültig ist - das heißt, irgendwo andere als unmittelbar nach einem Syscall fehlgeschlagen, so ist das Testen der Ergebniscodes Ihrer Operationen von entscheidender Bedeutung.

Wenn open taten tatsächlich falsch Rückkehr für Sie, und Sie fanden ENOTTY in $! dann würde ich dies einen kleinen Fehler betrachtet (einen nutzlosen Wert von $! geben), aber ich würde auch sehr gespannt sein, wie es passiert ist. Code und/oder Fachwerkausgabe wäre geschickt.

+0

Memoizing gut vor dem tatsächlichen Gebrauch/Notwendigkeit. wo ist das ein wenig verschwendung ist auf einem busy server öffnen/schließen sockets ... die perl auch testet um zu sehen, ob sie tty's sind –

4

"Ungültige ioctl für Gerät" ist die Fehlerzeichenfolge für den ENOTTY-Fehler. Es wurde früher durch Versuche ausgelöst, Terminaleigenschaften (z. B. den Echomodus) für einen Dateideskriptor zu konfigurieren, der kein Terminal war (sondern beispielsweise eine reguläre Datei), daher ENOTTY. Allgemeiner wird es ausgelöst, wenn ein ioctl auf einem Gerät ausgeführt wird, das dieses ioctl nicht unterstützt, daher die Fehlerzeichenfolge.

Um herauszufinden, was ioctl gemacht wird, das fehlschlägt, und auf welchen Dateideskriptor, führen Sie das Skript unter strace/truss aus. Sie erkennen ENOTTY, gefolgt von dem eigentlichen Ausdruck der Fehlermeldung. Finden Sie dann heraus, welche Dateinummer verwendet wurde und welcher Aufruf von open() diese Dateinummer zurückgegeben hat.

5

"Dateien" in * Nix-Typ-Systeme sind sehr ein abstraktes Konzept.

Sie können Bereiche auf der Festplatte sein, die von einem Dateisystem organisiert werden, aber sie können auch eine Netzwerkverbindung, ein bisschen gemeinsamen Speicher, die Pufferausgabe eines anderen Prozesses, eines Bildschirms oder einer Tastatur sein.

Damit Perl wirklich nützlich ist, spiegelt es dieses Modell sehr genau und behandelt keine Dateien, indem es ein Magnetband emuliert, wie es viele 4gls tun.

So versuchte es eine "IOCTL" -Operation "zum Schreiben öffnen" auf einem Datei-Handle, die keine Schreibvorgänge erlaubt, was eine ungeeignete IOCTL-Operation für dieses Gerät/diese Datei ist.

Die einfachste Sache zu tun ist, halten eine "or die 'Cannot open $myfile' Aussage am Ende von Ihnen geöffnet und Sie können Ihre eigene aussagekräftige Nachricht wählen.

18

Odd Fehler wie‚unangemessene ioctl für device‘sind in der Regel ein Ergebnis $ zu prüfen ! irgendwann andere als nur nach einem Systemaufruf ist fehlgeschlagen. Wenn Sie Ihren Code zeigen würde, ich wette, jemand schnell Ihre Fehler hinweisen würde.

+0

"' '' 'immer überprüfen" $! "? Zum Beispiel, 'sterben" mein schlechtes! \ N "' bezieht sich nicht explizit auf '$!' - aber ich bekomme die Fehlermeldung des OP. – wcochran

+0

@wcochran: sterben würde nicht eine Nachricht basierend auf $ 1 zeigen, aber es kann den Fehlercode für den Prozess ändern (das wird '$! || $? >> 8 || 255') – ysth

+0

Also mit' sterben 'sollte nur für Fehler verwendet werden, die von Systemaufrufen erzeugt werden, nehme ich an. Vielen Dank. – wcochran

2

Eureka Moment!

Ich hatte diesen Fehler vorher.

Bitte benutzen Sie die Perl-Debugger mit so etwas wie aufrufen: -

perl -d yourprog.pl > log.txt 

Wenn ja, was los ist perl Debug versucht vielleicht abzufragen und die Anschlussbreite zurückgesetzt. Wenn stdout kein Terminal ist, schlägt dies mit der IOCTL-Nachricht fehl.

Die Alternative wäre für Ihre Debug-Sitzung für immer hängen, weil Sie die Eingabeaufforderung für Anweisungen nicht angezeigt wurde.

0

Dieser Fehler ist heute bei dem Versuch aufgetreten, Code zu verwenden, um einen Ordner/Dateien zu löschen, die auf einer Windoze 7-Box gespeichert sind, die als Freigabe auf einem Centos-Server bereitgestellt wird. Habe den unpassenden Icotl für Gerätefehler bekommen und alles versucht, was mir in den Sinn kam. Lesen Sie über jeden Beitrag im Internet zu diesem Thema.

Offensichtlich wurde das Problem auf die bereitgestellte Windoze-Freigabe auf dem Linux-Server isoliert. Sah bei den Dateiberechtigungen für die Windoze-Box und notierte, dass die Berechtigungen der Dateien auf schreibgeschützt gesetzt waren.

Diese geändert, ging zurück auf den Linux-Server und alles funktionierte wie erwartet. Dies ist vielleicht nicht die Lösung für die meisten, aber hoffentlich spart es einige Zeit.

0

Ich habe versucht, den folgenden Code, der schien zu funktionieren:

if(open(my $FILE, "<File.txt")) { 
    while(<$FILE>){ 
    print "$_";} 
} else { 
    print "File could not be opened or did not exists\n"; 
} 
1

ich diesen Perl-Bug nur behoben. Siehe https://rt.perl.org/Ticket/Display.html?id=124232

Wenn wir die Pufferschicht PerlIO schieben und überprüfe eine versagende isatty() , die offensichtlich auf alle normalen Dateien fehlschlägt, ignorieren die falsche errno ENOTTY.