perl-“设备不适当的ioctl”

我在AIX框中运行一个Perl脚本。

该脚本尝试从某个目录打开文件,但由于文件没有读取权限,因此无法读取该文件,但是出现了另一个错误,提示strace

它不应该说strace之类的字吗?

strace消息是什么意思?

我该如何解决?

编辑:这是我做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)
someguy asked 2020-02-14T10:20:37Z
9个解决方案
37 votes

这很可能意味着打开未失败。

当Perl打开文件时,它通过向文件发出ENOTTY ioctl来检查文件是否为TTY(以便它可以回答open filetest运算符)。 如果文件是常规文件而不是tty,则ioctl失败并将errno设置为$!(字符串值:“设备的不适当的ioctl”)。 正如ysth所说,在$!中看到意外值的最常见原因是在无效时(即在系统调用失败后立即进行检查的其他地方除外)对其进行检查,因此测试操作的结果代码至关重要。

如果open实际上确实为您返回了false,并且您在$!中找到了ENOTTY,那么我会认为这是一个小错误(给出了$!的无用值),但我也非常想知道它是如何发生的。 代码和/或桁架输出将很漂亮。

hobbs answered 2020-02-14T10:31:34Z
21 votes

诸如“设备不适当的ioctl”之类的奇怪错误通常是检查$!的结果! 在系统调用失败之后的某个时刻。 如果您显示代码,我敢打赌,有人会迅速指出您的错误。

ysth answered 2020-02-14T10:31:55Z
5 votes

* nix类型系统中的“文件”非常抽象。

它们可以是由文件系统组织的磁盘上的区域,但同样可以是网络连接,少量共享内存,其他进程的缓冲区输出,屏幕或键盘。

为了使perl真正有用,它非常紧密地镜像了该模型,并且不像许多4gl那样通过模拟磁带来处理文件。

因此,它在文件句柄上尝试了“为写入而打开”的“ IOCTL”操作,该操作不允许进行写操作,这对于该设备/文件而言是不合适的IOCTL操作。

最简单的方法是在打开的结尾处贴上“ or die 'Cannot open $myfile'”语句,然后您可以选择自己的有意义的消息。

James Anderson answered 2020-02-14T10:32:36Z
4 votes

“设备的不合适的ioctl”是ENOTTY错误的错误字符串。 过去,它主要是通过尝试在不是终端(但是常规文件)的文件描述符上配置终端属性(例如回显模式)来触发的,因此是ENOTTY。 更一般而言,它在不支持该ioctl的设备上执行ioctl时触发,因此会触发错误字符串。

要找出导致失败的ioctl以及在哪个文件描述符上运行,请在strace / truss下运行脚本。 您将认识到ENOTTY,然后实际打印错误消息。 然后找出使用了哪个文件号,以及哪个open()调用返回了该文件号。

Martin v. Löwis answered 2020-02-14T10:33:01Z
3 votes

我刚刚修复了该Perl错误。参见[https://rt.perl.org/Ticket/Display.html?id=124232]

当我们将缓冲层推送到PerlIO并执行失败的isatty()检查时显然对所有普通文件都失败,请忽略错误的errno ENOTTY。

rurban answered 2020-02-14T10:33:26Z
2 votes

尤里卡时刻!

我以前有这个错误。

您是否使用过类似的方法调用perl调试器:

perl -d yourprog.pl > log.txt

如果是这样,perl debug会尝试查询并可能重置终端宽度。如果stdout不是终端,它将失败并显示IOCTL消息。

替代方法是使调试会话永久挂起,因为您没有看到提示的提示。

James Anderson answered 2020-02-14T10:34:03Z
1 votes

由于这是一个致命错误,并且也很难调试,因此可以将修复程序放在某个地方(在提供的命令行中?):

export GPG_TTY=$(tty)

来自:[https://github.com/keybase/keybase-issues/issues/2798]

Felipe answered 2020-02-14T10:34:28Z
0 votes

今天尝试使用代码删除位于作为Centos服务器上的共享安装的Windoze 7盒上的文件夹/文件时遇到此错误。 遇到了不适当的icotl设备错误,并尝试了所有想到的事情。 阅读网络上与此相关的每篇文章。

显然,问题仅在于Linux服务器上已安装的Windoze共享。 看了在“ Windoze”框中的文件权限上,并注意文件的权限设置为只读。

更改了这些,返回到Linux服务器,所有工作均按预期进行。 对于大多数人来说,这可能不是解决方案,但希望它可以节省一些时间。

Daniel Golembiewski answered 2020-02-14T10:34:57Z
0 votes

我尝试了以下似乎有效的代码:

if(open(my $FILE, "<File.txt")) {
    while(<$FILE>){
    print "$_";}
} else {
    print "File could not be opened or did not exists\n";
}
Nitish answered 2020-02-14T10:35:17Z
translate from https://stackoverflow.com:/questions/1605195/inappropriate-ioctl-for-device