74

我有一个在 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 或 TCGETS, 0xbffc14f8) = -1 ENOTTY
    (设备的 ioctl 不合适)
4

10 回答 10

49

很可能这意味着 open没有失败

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

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

于 2009-10-22T07:20:14.987 回答
24

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

于 2009-10-22T06:31:02.400 回答
9

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

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

于 2009-10-22T06:06:25.007 回答
9

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

export GPG_TTY=$(tty)

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

于 2019-04-27T00:04:33.717 回答
7

*nix 类型系统中的“文件”是一个非常抽象的概念。

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

为了使 perl 真正有用,它非常接近地反映了这个模型,并且不像许多 4gls 那样通过模拟磁带来处理文件。

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

or die 'Cannot open $myfile' 最简单的做法是在您打开的末尾贴上“声明”,您可以选择自己的有意义的信息。

于 2009-10-22T06:07:40.390 回答
4

我刚刚修复了这个 perl 错误。见https://rt.perl.org/Ticket/Display.html?id=124232

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

于 2015-04-03T10:31:38.463 回答
2

尤里卡时刻!

我以前遇到过这个错误。

你有没有用类似的东西调用 perl 调试器:-

perl -d yourprog.pl > log.txt

如果是这样,发生了什么是 perl 调试尝试查询并可能重置终端宽度。当 stdout 不是终端时,这将失败并显示 IOCTL 消息。

另一种方法是让您的调试会话永远挂起,因为您没有看到指示提示。

于 2009-10-22T08:21:21.683 回答
0

今天在尝试使用代码删除作为共享安装在 Centos 服务器上的 Windoze 7 盒子上的文件夹/文件时遇到了这个错误。得到了不合适的 icotl 设备错误并尝试了所有想到的东西。阅读网络上与此相关的几乎所有帖子。

显然,问题与 Linux 服务器上挂载的 Windoze 共享有关。查看 Windoze 框上的文件权限,并注意到文件的权限设置为只读。

改变了这些,回到 Linux 服务器,一切都按预期工作。这可能不是大多数人的解决方案,但希望它可以节省一些时间。

于 2013-03-10T18:16:50.890 回答
0

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

if(open(my $FILE, "<File.txt")) {
    while(<$FILE>){
    print "$_";}
} else {
    print "File could not be opened or did not exists\n";
}
于 2015-02-04T17:44:57.187 回答
0

Can't open file for reading. Inappropriate ioctl for device最近,当我将带有基于 DBM 文件的数据库的旧 UB2K 论坛迁移到新主机时,我遇到了错误。显然,DBM 有多种不兼容的实现。我有数据库的备份,所以我能够加载它,但似乎还有其他选择,例如将 perl 脚本/dbm 移动到新服务器,并移出 dbm?.

于 2020-12-11T08:03:01.990 回答