【问题标题】:How to check for piped data in perl script如何在 perl 脚本中检查管道数据
【发布时间】:2015-08-06 09:51:40
【问题描述】:

我目前正在使用这两个 if 语句来确定数据是通过管道输入还是来自文件:

pod2usage("$NAME: Requires at least one argument FILE.\n") if ((-t STDIN) && (@ARGV == 0));
pod2usage("$NAME: zero if input is from STDIN.\n") if (!(-t STDIN) && (@ARGV != 0));

当 perl 脚本从 shell 以交互方式运行时,这可以正常工作。例如,这些按预期工作:

$ perl_script <flags> filename
$ cat | perl_script <flags>

但是,当从 bash 脚本或 emacs 中的 org-mode 之类的东西调用 perl 脚本时,脚本认为它正在通过管道输入数据,并在文件作为参数给出时抛出 pod2usage 错误。以下是导致此行为的示例:

#!/bin/bash
while read line
do
perl_script <flags> $line  >> output_file
done < file_names.txt

我猜这是因为 -t STDIN 正在返回 false,因为它是以非交互方式运行的,因此它没有连接到终端。如果脚本以交互方式运行或从 shell 脚本调用,有没有办法确保我得到正确的行为?

【问题讨论】:

  • -t 返回 true,即使您的脚本不在管道的读取端:perl -wE 'say "tty" if -t'。了解某些内容是否正在传递给 STDIN 的唯一方法是尝试从中读取。
  • @ThisSuitIsBlackNot 你能举个例子吗?
  • while (&lt;&gt;) { ... }。如果您不将文件名作为参数或管道数据传递给 STDIN,这将阻塞并等待输入,这正是 *nix 实用程序(例如 catawkwc)通常所做的。换句话说,我会删除您现在拥有的支票;您无法可靠地测试用户是否正在向 STDIN 输入内容(他们可能在您进行检查时正在输入内容),所以不要尝试。相反,做现有程序所做的事情:允许用户将文件名作为参数传递,通过管道输入数据,或通过提示手动输入。
  • 我认为,如果@ARGV != 0,你应该直接忽略stdin
  • @ThisSuitIsBlackNot 谢谢。更新了我的脚本以像其他 *nix coreutils 一样工作,现在一切正常。

标签: linux bash perl shell stdin


【解决方案1】:

试试这个:

#!/bin/bash
TTY=`tty`
while read line
do
perl_script <flags> $line  < $TTY >> output_file
done < file_names.txt

【讨论】:

    【解决方案2】:

    外部脚本将 STDIN 上的 file_names.txt 提供给循环,循环中的任何子进程都会获取该文件。您的逻辑(就您的内部脚本而言)是正确的。但是,它以两种方式获取输入:命令行上的文件名和作为 STDIN 上的 file_names.txt 文件的重定向,提供给未连接到 tty 的循环。这是我对 bash 循环的主要抱怨之一。 STDIN 重定向是一种松散的规范,并在不知不觉中被循环内容拾取。这也是我喜欢 tcsh 的 foreach 的原因:

    #!/bin/tcsh
    foreach line ( `cat file_names.txt` )
      perl_script <flags> $line  >> output_file
    end
    

    您也可以在 bash 中执行类似的操作,但我不确定您的内部脚本是否会在 STDIN 上获取父脚本的句柄(因为我对 bash 还很陌生,并且一直在使用 tcsh几十年)。不过你可以试试看是否可行:

    for line in `cat file_names.txt`; do perl_script <flags> $line  >> output_file; done
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多