【问题标题】:Shell command execution from perl script contains garbage characters从 perl 脚本执行的 Shell 命令包含垃圾字符
【发布时间】:2017-01-09 11:25:53
【问题描述】:

我有一个 perl 脚本,它运行一个 shell 命令并解析输出,如下所示:

# Using ls -ltr for illustration. Actual command is different.
my $cmd = "ls -ltr 2>&1 | ";
open (CMD, $cmd ) || die "Cant run $cmd";

while (my $line = <CMD>) {
  chomp $line;
  ...
  ...
}

即使在使用chomp 之后,上述$line 也包含垃圾字符。我已经尝试将输出重定向到文件并从文件中读取,但即使文件中仍然包含垃圾/垃圾字符。

执行上述命令的示例输出:

^[[H^[[Jtotal 12
drwx------ 2 root root 4096 Dec 19 15:30 tad4d
drwx------ 2 root root 4096 Jan  2 15:37 oup
-rw-r--r-- 1 root root  137 Jan  9 06:25 alth.txt

在上面的输出中,在total 12之前,有一些乱码。

  1. 垃圾字符进入 shell 命令输出的原因可能是什么?
  2. 如何避免垃圾/垃圾字符?

谢谢

【问题讨论】:

  • 需要一个“垃圾”的例子才能回答。
  • 添加了示例输出!!
  • ^[ 是转义码。您是否配置了提示,尤其是带有颜色的提示? (echo $PS1 应该告诉你)
  • ^[[H^[[J 是垃圾

标签: perl


【解决方案1】:

1 - 在不知道命令的情况下无法回答。如果它是ls,你不应该解析ls,但你表明你不是。使用您提供的示例输入:^[[H^[[J - 是一个转义码,用于终端中的颜色之类的东西。见:Control Sequences -

可能来自您的提示。检查 $PS1 在您的 shell 中设置的内容。但是有一个解决方法,涉及绕过 shell:

open ( my $output, '-|', 'ls', '-ltr' );
while ( <$output> ) { 
     print;
}

这样你就不会让 shell 参与处理,所以任何“垃圾”都直接来自你正在运行的命令。

见:perlfaq

2 - 修复命令不生成“垃圾”。我不能更具体,因为我不知道你的意思。但是通过正则表达式运行它以过滤掉特定的“垃圾”字符是非常可行的。例如。 s/[^\w\s]+//g 将过滤掉任何不是字母数字和空格的内容。虽然注意 - 这将删除标点符号,但您可以通过阅读perlre 找出更合适的示例

但在您的示例中 - 因为它是转义码 - 您获得的不仅仅是控制码,而是转义序列。过滤起来可能更烦人,因为它们没有固定的长度。但也许这会有所帮助:Best way to remove ANSI color escapes in Unix

我会指出作为补充 - 3 参数 open 使用词法文件句柄是一种很好的做法,并且可以避免一些陷阱。

【讨论】:

  • 使用-c时不使用提示,所以不是来自提示。可能来自一个写得不好的 shell 启动文件。这是clear发出的序列。
【解决方案2】:

您已将 shell 配置为在启动时调用 clear。这些字符由clear 发出,以指示您的终端将光标归位并自行清除。您应该限制调用 clear 以登录 shell 和/或交互式 shell。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 2012-07-21
    • 2018-02-27
    • 2018-03-29
    • 1970-01-01
    • 2014-03-03
    相关资源
    最近更新 更多