【问题标题】:How can I obtain unmodified command line arguments to "wrap" another command line tool?如何获取未修改的命令行参数以“包装”另一个命令行工具?
【发布时间】:2010-12-18 10:51:03
【问题描述】:

我想编写一个脚本 foo,它只是使用 Bash 或 Perl 调用 bar 时使用完全相同的参数。

现在,在 perl 中执行此操作的一种简单方法是

#!/bin/perl

my $args=join(' ', @ARGV);
`bar $args`;

但是,ARGV 中的值已经被 shell 处理过,因此如果我调用

 foo "I wonder, \"does this work\""

bar 会这样调用

 bar I wonder "does this work"

我怎样才能获得原始命令行,以便我可以简单地逐字传递?

【问题讨论】:

    标签: perl bash command-line


    【解决方案1】:

    在 shell 处理它们之前,您无法获取 perl 可执行文件的参数。但是,您可以确保 shell 不会再次处理它们

    system('bar', @ARGV);
    

    对比

    system("bar @ARGV");
    

    perldoc -f system:

    如果有 只有一个标量参数,检查该参数是否有 shell 元字符,如果有,则将整个参数传递给系统的 用于解析的命令 shell(在 Unix 平台上是“/bin/sh -c”,但在其他平台上有所不同)。如果没有 shell 元字符 参数,分词直接传给“execvp”,效率更高。

    如果需要读取程序的输出,请使用进程句柄,并以相同的方式传递参数(无需插值):

    open my $barhandle, '-|', 'bar', @ARGV or die "Can't call bar: $!";
    while (my $line = <$barhandle>)
    {
        # do something with $line...
    }
    close $barhandle;
    

    您可以通过多种方式调用 Perl 中的程序;请参阅 What's the difference between Perl's backticks, system, and exec? 了解主要选项的概览。

    【讨论】:

    • 当然,一个考虑是 system() 的返回值是程序执行的返回值,而不是程序的输出。如果您尝试收集其输出,则可能需要将输出重定向到文件并读取该文件。
    • @atk:在这种情况下,您可以使用进程句柄。
    • @ysth:确实,我们之前甚至已经讨论过这个问题:stackoverflow.com/questions/799968/…
    • 感谢您的详细回答:)
    【解决方案2】:

    这非常简单。查看系统调用的 system(LIST) 变体。

    system('bar', @ARGV);
    

    perldoc -f 系统

    【讨论】:

      【解决方案3】:

      在 bash 中:

      exec bar "$@"
      

      这会保留参数中的间距。但是,I/O 重定向不是术语含义内的参数(但为原始调用所做的 I/O 重定向将持续到调用的“bar”命令,除非您更改它)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2015-05-20
        • 1970-01-01
        • 2013-10-15
        • 2017-04-30
        相关资源
        最近更新 更多