我有一个在AIX框中运行的Perl脚本。
该脚本尝试从某个目录打开文件,但由于该文件没有读取权限,因此无法读取该文件,但我收到的错误是inappropriate ioctl for device
。
不应该说no read permissions for file
或类似的东西吗?
此inappropriate ioctl for device
消息的含义是什么?
我该如何解决?
编辑:这是我在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)
答案 0 :(得分:35)
很可能这意味着打开的没有失败。
当Perl打开一个文件时,它会通过发出-T $fh
ioctl来检查该文件是否是TTY(以便它可以回答TCGETS
filetest操作符)。如果文件是常规文件而不是tty,则ioctl失败并将errno设置为ENOTTY
(字符串值:“设备的不适当的ioctl”)。正如ysth所说,在$!
中看到意外值的最常见原因是在无效时检查它 - 也就是说,其他,而不是在系统调用失败后立即检查它,因此测试您的运营结果代码至关重要。
如果open
确实为您返回了false,并且您在ENOTTY
中找到了$!
,那么我会认为这是一个小错误(给出$!
无用的值但我也很好奇它是如何发生的。代码和/或桁架输出会很漂亮。
答案 1 :(得分:19)
奇怪的错误,例如“设备不合适的ioctl”通常是检查$的结果!在系统调用失败之后的某个时刻。如果你显示你的代码,我打赌有人会迅速指出你的错误。
答案 2 :(得分:5)
它们可以是由文件系统组织的磁盘上的区域,但它们同样可以是网络连接,一些共享内存,来自另一个进程的缓冲区输出,屏幕或键盘。
为了让perl非常有用,它会非常密切地反映这个模型,并且不会通过模拟磁带来处理文件,而不是4gls。
因此它尝试在文件句柄上执行“IOCTL”操作“open for write”,该操作不允许对该设备/文件进行不恰当的IOCTL操作的写操作。
最简单的方法是在打开结束时粘贴“or die 'Cannot open $myfile'
语句,然后您可以选择自己有意义的信息。
答案 3 :(得分:4)
“不适当的设备ioctl”是ENOTTY错误的错误字符串。它曾经主要是通过尝试在没有终端(但是,例如,常规文件)的文件描述符上配置终端属性(例如回声模式)来触发,因此是ENOTTY。更一般地说,它是在不支持ioctl的设备上执行ioctl时触发的,因此是错误字符串。
要找出失败的ioctl,以及在什么文件描述符上,运行strace / truss下的脚本。您将识别ENOTTY,然后实际打印错误消息。然后找出使用了什么文件号,以及open()调用返回该文件号。
答案 4 :(得分:2)
之前我遇到过此错误。
您是否通过以下方式调用perl调试器: -
perl -d yourprog.pl > log.txt
如果是这样,perl调试尝试查询并可能重置终端宽度。 当stdout不是终端时,它会因IOCTL消息而失败。
另一种方法是让你的调试会话永远挂起,因为你没有看到提示说明。
答案 5 :(得分:2)
我刚修复了这个perl bug。 见https://rt.perl.org/Ticket/Display.html?id=124232
当我们将缓冲层推送到PerlIO并执行失败的isatty()检查时 显然在所有正常文件上失败,忽略错误的错误ENOTTY。
答案 6 :(得分:1)
由于这是一个致命错误,而且调试起来也很困难,所以也许可以将修复程序放在某个地方(在提供的命令行中?):
export GPG_TTY=$(tty)
答案 7 :(得分:0)
今天遇到此错误,同时尝试使用代码删除生活在作为Centos服务器上的共享的Windoze 7盒子上的文件夹/文件。得到了不恰当的icotl设备错误,并尝试了所有想到的。阅读网上与此相关的每篇文章。
显然,问题与Linux服务器上挂载的Windoze共享隔离。看着 在Windoze框的文件权限上,并注意到文件的权限设置为只读。
更改了这些,返回Linux服务器,所有工作都按预期工作。这对大多数人来说可能不是解决方案,但希望能节省一些时间。
答案 8 :(得分:0)
我尝试了以下似乎有用的代码:
if(open(my $FILE, "<File.txt")) {
while(<$FILE>){
print "$_";}
} else {
print "File could not be opened or did not exists\n";
}
答案 9 :(得分:0)
最近,当我将具有基于DBM文件的数据库的旧UB2K论坛迁移到新主机时,收到错误Can't open file for reading. Inappropriate ioctl for device
。显然,有多个不兼容的DBM实现。我有数据库的备份,所以我能够加载它,但似乎还有其他选择,例如moving a perl script/dbm to a new server, and shifting out of dbm?。