0

我正在尝试在 Windows 上创建一个颠覆预锁挂钩。但是,我对文件名中的 & 符号有严重的问题:

如果路径包含空格,svn 似乎会在我的批处理文件调用中将双引号(“)放在我要锁定的文件周围。但是,如果我的文件名包含&符号(&)并且没有空格,则没有双引号Windows 认为这是第二次调用,我的脚本没有得到正确的文件名。

正如您在日志文件中看到的那样,我无法正确处理 & 符号,因为 windows command.com 将转义引号与非转义引号解释相同:

>perl pre-lock.pl repo \""one & two"\" name

将始终失败,并显示“'two' 未被识别为内部或外部命令、可运行程序或批处理文件。”

这是 command.com 中的错误吗?

供参考和自我尝试,这是我的文件:

@echo off
echo %1 %2 %3 >> c:\hooktest.txt
set SCRIPTS=c:/scripts
SET PERL=C:/Perl/bin/perl.exe
%PERL% -w -I%SCRIPTS% "%SCRIPTS%/pre-lock.pl" \"%1\" \"%2\" \"%\3\"
set err=%errorlevel%
exit %err% 

一个小的调试 perl 脚本:

use Data::Dumper;
 print STDERR "This are the arguments:\n";
 print STDERR Dumper(@ARGV);
 exit 1;

在我的 Hook 日志中记录了以下内容:

c:\repo /test/file_nospace.txt pparker 
c:\repo "/test/file with space" pparker 
c:\repo "/test/file with & ampersand.txt" pparker 
c:\repo /test/file_with_&_ampersand.txt pparker 
4

1 回答 1

1

首先,这(希望)与 command.com 无关,因为 cmd.exe 正在执行批处理文件。

然而,是的,shell 引用不同。它不是 Unix shell,也不必遵守那里的约定。

不过我想知道,为什么你需要两个级别的引号。用空格和 & 号在参数周围加上一层引号就足以将其作为一个参数发送到另一个程序:

%PERL% -w -I%SCRIPTS% "%SCRIPTS"\pre-lock.pl" %1 %2 %3

由于您只是将参数传递给批处理,因此无需在此处添加更多引号。批处理参数保留引号。另一种方法是:

%PERL% -w -I%SCRIPTS% "%SCRIPTS"\pre-lock.pl" "%~1" "%~2" "%~3"

它明确地去除引号,然后再次添加它们。

(不过,老实说,我不知道如何将用引号括起来的参数传递给另一个程序,以便程序看到"foo"而不是foo. 但我很确定在这种情况下这不是问题。)

无论如何,您的批处理文件中也存在一些错误和奇怪之处:

  1. 尝试养成使用反斜杠而不是正斜杠的习惯。cmd 使用斜杠作为命令选项,因此内置命令很少会看到它们。Windows API 很乐意接受斜杠代替反斜杠。不过,shell 对它们并不满意。
  2. 最后两行没有任何用处。我猜你想要

    exit /b %errorlevel%
    
于 2010-12-18T01:48:15.503 回答