Windows 上文件名中存在与号和空格的 svn 预锁定钩子处理缺陷

发布于 2024-10-07 09:09:46 字数 1080 浏览 0 评论 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 

I am trying to create a subversion pre-lock hook on windows. However I have serious problems with ampersand in filenames:

It seems svn will place double quotes(") around my file-to-be-locked in my call to my batch file, if the path contains spaces. However If my filename contains ampersand (&) and no spaces there are no double quotes and windows think it is a second call and my script does not get the correct filename.

As you can see in logfile, I cannot handle ampersand correctly because windows command.com is interpreting the escaped quotes the same as the non escaped:

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

will always fail with "'two' is not recognized as an internal or external command,
operable program or batch file."

Is this an Error in command.com?

For reference and self trying, here are my files:

@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% 

a small debug perl script:

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

In my Hook log the following is logged:

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 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乱世争霸 2024-10-14 09:09:46

首先,这(希望)与 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 很乐意接受斜杠来代替反斜杠。不过,贝壳对它们不太高兴。
  2. 最后两行没有做任何有用的事情。我猜你想要

    退出 /b %errorlevel%
    

First of all, this has (hopefully) nothing to do with command.com, as cmd.exe is executing batch files.

Nevertheless, yes, the shell quotes differently. It is no Unix shell and does not have to adhere to conventions there.

I wonder though, why you need two levels of quotes there. Putting a single level of quotes around the argument with spaces and ampersand suffices to send it as one argument to another program:

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

Since you are just passing arguments to the batch around, there is no need to put more quotes there. Batch arguments retain the quotes. Another way would be:

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

which explicitly strips the quotes and then adds them again.

(Honestly, though, I have no idea how to pass an argument surrounded by quotes to another program so that the program sees "foo" and not foo. But I'm fairly sure that this isn't a problem in this case.)

In any case, there are a few errors and weirdnesses in your batch file as well:

  1. Try making it a habit of using backslashes instead of forward slashes. cmd uses slashes for command options and therefore built-in commands are rarely happy to see them. The Windows API will happily accept slashes in place of backslashes. The shell isn't so happy about them, though.
  2. The last two lines are doing nohing useful. I guess you wanted

    exit /b %errorlevel%
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文