如何使用exec进行'svn checkout URL'?



我正在尝试使用 Tcl 脚本使用 svn 从 Github 中查看 Joe English 的磁贴附加内容。

所需的命令是

svn checkout https://github.com/jenglish/tile-extras.git path

我有一些代码可以归结

exec C:/cygwin64/bin/svn.exe checkout                
https://github.com/jenglish/tile-extras.git C:/cygwin64/tmp/TCL61416]

失败并显示消息

couldn't execute "C:cygwin64binsvn.exe checkout
https:github.comjenglishtile-extras.git 
C:cygwin64tmpTCL61416": No error

将错误消息中引用的命令粘贴到 Windows 命令提示符窗口中,我看到

svn: E125002: 'https:github.comjenglishtile-extras.git' does not appear to be a URL

所以,问题似乎是exec过于热情地将Tcl风格的路径转换为Unix风格。有什么方法可以防止它将https://github.com/jenglish...转换为https:github.comjenglish...

有关信息,我在Windows 10上运行,使用cygwin(安装版本2.889(64位)),svn 1.9.7和tcl版本8.6.7(通过ActiveTcl 8.6.7.0)。

更新

这是我的实际代码,我只是有点尴尬:

# svn wrapper proposed by Donal Fellows at
# http://stackoverflow/questions/49224268
proc svn {args} {
exec {*}[auto_execok svn] {*}$args <@stdin >@stdout }
# Checkout from github to a temporary repository
set repository https://github.com/jenglish/tile-extras.git set
svnImage [auto_execok svn]
set fil [file tempfile tempfnm] close $fil file delete $tempfnm
set tempRepo [file rootname $tempfnm] puts stdout tempRepo: $tempRepo
file mkdir $tempRepo
set svnCmd [list svn checkout $repository [file nativename $tempRepo]]
puts stdout svnCmd: $svnCmd eval $svnCmd
# Determine the tile-extras sources
set sourceFiles {keynav.tcl icons.tcl}
set targets [file nativename [file join $tempRepo trunk *.tcl]]
foreach filnam [split [svn ls $targets] n] {
if {[string match *.tcl $filnam] && [lsearch $sourceFiles $filnam] < 0}  {
lappend sourceFiles $filnam
}
}

这是结果

$ tclsh foo.tcl
tempRepo: C:/cygwin64/tmp/TCL61838
svnCmd: svn checkout
https://github.com/jenglish/tile-extras.git {C:cygwin64tmpTCL61838}
A    C:cygwin64tmpTCL61838/branches
A    C:cygwin64tmpTCL61838/trunk
A    C:cygwin64tmpTCL61838/trunk/README.md
A    C:cygwin64tmpTCL61838/trunk/dialog.tcl
A    C:cygwin64tmpTCL61838/trunk/doc
A    C:cygwin64tmpTCL61838/trunk/doc/dialog.n
A    C:cygwin64tmpTCL61838/trunk/doc/keynav.n
A    C:cygwin64tmpTCL61838/trunk/icons.tcl
A    C:cygwin64tmpTCL61838/trunk/keynav.tcl
A    C:cygwin64tmpTCL61838/trunk/license.terms
A    C:cygwin64tmpTCL61838/trunk/pkgIndex.tcl
Checked out revision 7.
svn: E155007: '/home/alan/C:cygwin64tmpTCL61838trunk*.tcl' is not a working copy
while executing "exec {*}[auto_execok svn] {*}$args <@stdin >@stdout"
(procedure "svn" line 2)
invoked from within "svn ls $targets"
invoked from within "split [svn ls $targets] n"
invoked from within "foreach filnam [split [svn ls $targets] n] {
if {[string match *.tcl $filnam] && [lsearch $sourceFiles $filnam] < 0} {
lappend sourceFiles $filn..."
(file "foo.tcl" line 30)
$ ls /tmp/TCL61838/
$

目录/tmp/TCL61838是空的,所以svn checkout命令似乎没有完全愉快地完成。我还看到svn报告了令人不快的正斜杠和反斜杠混合。

提前感谢您的更多帮助。

鉴于错误消息,看起来您在未向我们展示的代码中弄错了单词边界; 虽然您可能认为代码"归结为"该exec,但实际上并没有这样做。此外,您已经翻转了 URL 中的斜杠,这不起作用,但这可能是其他事情的副作用。

唉,我不太能猜到如何为你解决问题。选择太多了。我在下面提供了一个建议,但不确定它是否会成功。

诊断方法

我为什么认为问题的证据是我所说的?此交互式会话日志(在 OSX 上,但通用行为应相同):

% exec cat asdkfajh
cat: asdkfajh: No such file or directory
% exec "cat akjsdhfdkj"
couldn't execute "cat akjsdhfdkj": no such file or directory
% exec "cat aksdjhfkdf" skdjfghd
couldn't execute "cat aksdjhfkdf": no such file or directory

第一种情况显示来自外部程序的错误。第二种情况显示由于没有此类程序而导致的错误。第三种情况表明,由于没有这样的程序而导致错误时,不会报告参数

这让我得出结论,C:cygwin64binsvn.exe及其参数(checkouthttps:github.comjenglishtile-extras.gitC:cygwin64tmpTCL61416)实际上都是作为一个参数传递给exec的,这是一个相当常见的错误,问题出在准备代码上。您没有向我们展示准备代码,因此我们无法真正解决问题,但我们可以提出解决常见问题的建议。

建议的方法

减少这些错误的好方法是编写一个小的包装过程:

proc svn {args} {
# I add in the I/O redirections so svn can ask for a password
exec {*}[auto_execok svn] {*}$args <@stdin >@stdout
}

这将允许您将调用 svn 编写为:

svn checkout $theURL [file nativename $theDirectory]

它可能会起作用™。另请注意,只有目录名称会经过file nativename;(如果我们要做一个专门的程序来做结账,我们可以在程序中嵌入对file nativename的调用,但是整个 svn 程序中的变化太大,无法让我们这样做。呼叫者 - 你 - 必须处理它。

最新更新