我正在尝试使用 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
及其参数(checkout
、https:github.comjenglishtile-extras.git
和C: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 程序中的变化太大,无法让我们这样做。呼叫者 - 你 - 必须处理它。