【问题标题】:Does Perl's system() automatically escape characters in Cygwin?Perl 的 system() 会自动转义 Cygwin 中的字符吗?
【发布时间】:2012-06-20 17:47:21
【问题描述】:

我有使用 system() 函数来调用 robocopy.exe 的 Perl 代码,但看起来它正在破坏参数。我正在使用 Chef,它通过 Cygwin 捆绑 Perl -“这是 perl,为 msys-64int 构建的 v5.8.8”。

我认为 Cygwin 正在转义一些字符,但 system() 不会显示它实际传递给 shell 的内容,所以我不知道如何正确格式化调用。

my $robocopyCmd = "robocopy.exe /a-:r /r:30 /w:10 c:/folder1 c:/folder2";
print "DEBUG: " . $robocopyCmd . "\n";
system($robocopyCmd);

这是输出。

DEBUG: robocopy.exe /a-:r /r:30 /w:10 c:/folder1 c:/folder2

-------------------------------------------------------------------------------
ROBOCOPY     ::     Robust File Copy for Windows     ::     Version XP010
-------------------------------------------------------------------------------

Started : Wed Jun 20 10:33:05 2012

Source - R:\30\
Dest - W:\10\

Files :
Options : /COPY:DAT /A-:R /R:1000000 /W:30

------------------------------------------------------------------------------

ERROR : Invalid Parameter #4 : c:/folder1

当我将调试输出剪切并粘贴到 shell(甚至是 Cygwin shell)中时,它运行得很好。但是,请查看 robocopy 输出,了解它告诉您 Source 和 Dest 的位置。请注意它如何将我的 /r:30 论点更改为 R:\30\

似乎某些东西(cygwin 或 perl 或 system())在将某些字符传递给 shell 之前会自动转义它们。问题是我无法看到它发生了什么变化,所以我不知道如何自定义我的命令才能正常工作!

请注意,如果我使用反引号而不是 system() 函数,则行为完全相同。

【问题讨论】:

  • 请注意,我尝试转义正斜杠和冒号。两者都对输出没有任何影响。

标签: perl cygwin system windows-shell


【解决方案1】:
system($shell_cmd);

从不逃避任何事情。能逃出什么?

问题是您试图在 bourne shell 中运行 Windows shell 命令。

system($shell_cmd)

简称

system('sh', '-c', $shell_cmd)

在 unix 系统上(包括 unix 仿真层,例如 Perl 的 cygwin 构建)。以下是否有效?

system('cmd', '/c', $robocopyCmd);

【讨论】:

  • 完美。我不得不硬编码“C:/windows/system32/cmd.exe”,因为 cygwin 完全破坏了 %PATH%,但我会想出一个更优雅的解决方案。现在,它工作得很好,谢谢!
  • Cygwin 在启动 shell 程序之前将 %PATH% 转换为相应的 POSIX 格式。使用 Cygwin 实用程序 cygpath 在 POSIX 格式(例如 /cygdrive/c/windows/system32)和 DOD/Windows 格式(例如 C:\windows\system32)之间进行转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
相关资源
最近更新 更多