0

我试图从 STDIN 文件描述符中读取/dev/fd/0

这就是我写的,我只想打印我在命令 shell 上输入的每个命令。我用 Perl 写了这个,但还不够好:

#!/usr/bin/perl

use strict;
use warnings;

open my $fh, "<", "/dev/fd/0" or die "bububububu";
while (<$fh>) {
print $_."\n";
}
close $fh;

因此,尽管卡住了,但它不会打印任何内容。有谁知道怎么做???如果这不可能,我可以将所有命令放在一个文件中,然后以某种方式从“0”文件句柄中读取它们。我只想捕获通过系统的每个命令。

示例文件:

#!/usr/bin/perl

use strict;
use warnings;

system("./.file2");

然后file2是:

echo this is hard!!!

所以我希望我的程序运行第一个文件。当我读取“0”文件句柄时,我希望以某种方式将所有运行的行存储在一个数组中。

主要编辑:我认为你误解了我。我知道标准输入及其工作原理。问题是我不希望从标准输入中读取脚本。我希望从我在 shell 提示中输入的内容中读取脚本。假设我运行文件,然后打开另一个终端,然后在终端中键入命令。我希望脚本能够识别这些行并将它们保存在一个数组中。

4

2 回答 2

2

禁令,我认为您尝试做的事情不会奏效。/dev/fd/0每个进程的句柄都不同(当你打开它时,你基本上会复制fh父进程继承的文件),所以你在 perl 中打开的文件句柄与你的 bash 不同。

不过,我相信您在这里(至少)有两个选择:

  1. 使用该方法读取您的命令while( <STDIN> ),然后将它们存储到您的文件中并将它们传递给shellsystem()$qx()由 shell 执行,但是,因为这会为每个命令启动一个 shell,这只适用于简单的应用程序。您可以通过在子子项中打开 shell 并将其 STDIN/STDOUT 文件句柄与 perl 文件句柄连接来解决此问题,您可以通过管道传输新命令并读出它们的输入。有关详细信息,请参阅perldoc perlopentut(管道打开部分)和/或IPC::Open2http://search.cpan.org/~rjbs/perl-5.18.0/ext/IPC-Open3/lib/IPC/Open2.pm)。结合Term::ReadLine您可以模拟 shell 的完整输入法,并且在记录所有命令时不会注意到太多差异。
  2. 您是否有任何理由不只使用bash 的历史功能(例如,请参见此处:http ://www.talug.org/events/20030709/cmdline_history.html )。默认情况下,您在交互式会话中执行的每个命令都应记录在 中~/.bash_history,您可以使用 `history.

如果您的应用程序与安全相关,并且您正在尝试记录例如root在系统上执行的所有操作,那么您可能还需要查看sudo.

希望这对你有帮助,克里斯蒂安

于 2013-08-07T08:35:45.243 回答
0

有一个与标准输入相关联的特殊 Perl 文件描述符。您可以将代码重写为:

use strict;
use warnings;

while( <STDIN> ) {
   print;
   last if /^QUIT/;  #Exit loop if QUIT was typed
}

#<-- Note: no open neither close
于 2013-08-07T07:47:48.437 回答