【问题标题】:Capturing output from a command specified in Perl array从 Perl 数组中指定的命令捕获输出
【发布时间】:2015-09-16 17:28:24
【问题描述】:

我认为这一定很简单,但我还没有找到可行的解决方案。

问题就这么简单:我想执行一个系统命令并在 Perl 变量中捕获输出。该命令在 Perl 数组中指定(包含命令和参数,例如 @cmd = ('mycmd', '-opt1', 'arg1', 'val1'))。

我不想使用分叉,即open(FROM_KID, '-|') 不是一个选项。我知道如果我有一个字符串中的命令,我可以用反引号来实现这一点。所以也许这个问题可以归结为将@cmd 数组转换为字符串。就我而言,命令参数可以包含空格。

有没有一种简单的方法可以将@cmd 数组转换为可以与反引号一起使用的字符串,但要正确引用所有参数?最好不要使用任何外部库。

谢谢!!

【问题讨论】:

  • 首先,使用 system 或 backtics 将分叉一个子进程 - 没有办法解决这个问题。你可以做类似$cmd = join(' ', map { s/'/\\'/g; "'$_'" } @cmd);open 可能会更安全..
  • Re“我不想用fork”,不fork是不可能的。这就是在 unix 中创建所有进程的方式,包括使用 system 时。
  • 这与system 和反引号所做的隐式分叉相同。
  • 你应该解释为什么你认为你不想 fork 一个子进程,以及为什么你不想使用 Perl 模块

标签: perl command


【解决方案1】:

您可能正在寻找String::ShellQuote。请注意,仅支持 Bourne shell 引用。

但是反引号也执行隐式分叉,如果它们与管道打开的隐式分叉有任何不同,我从来没有注意到。 :-\

【讨论】:

  • String::ShellQuote 是第三方包,我想避免。我们有一个现有的脚本,它只使用核心包并支持 Perl 回到 5.8 版。我只需要让它在 Windows 下工作,可能不会影响最低要求或添加对不在核心中的包的依赖。
  • String::ShellQuote 是纯粹的 Perl——你可以从中复制代码。但它只适用于 Bourne shell,不适用于 Windows 的 command.exe/cmd.exe。在 Windows 上,您需要 Win32::ShellQuote – 或一个足够新的 perl 版本,以便管道打开工作。 ;-)
  • Win32::ShellQuote 似乎是借用代码的地方。谢谢!
猜你喜欢
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 2022-01-14
相关资源
最近更新 更多