我在.bat中有以下内容(这可行):
"%winscp%" /ini=nul ^
/log=C:\TEMP\winscplog.txt ^
/command "open scp://goofy:changeme@10.61.10.225/ -hostkey=""ssh-rsa 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d""" ^
"put ""%outfile%"" /home/public/somedir/somesubdir/%basename%" ^
"exit"
我试图将其复制到像这样的PowerShell脚本中:
& $winscp "/ini=nul" `
"/log=C:\TEMP\winscplog.txt" `
"/command" 'open sftp://goofy:changeme@10.61.10.225/ -hostkey="ssh-rsa 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d"' `
"put `"" + $outfile + "`" /home/public/somedir/somesubdir/" + $basename `
"exit"
当我运行.bat脚本时,文件将上传。
当我运行.ps1脚本时,我得到Host key does not match configured key ssh-rsa
我怀疑我没有在powershell中正确格式化命令,并且在winscp看到它的时候主机密钥被破坏了。
我检查了日志,显示的所有内容都是来自主机的主机密钥。它没有显示我正在使用的密钥。我确认通过更改我的主机并注意到它没有显示在日志中。我比较了.bat和.ps1之间的日志,差异是ps1终止了上面提到的错误。
winscp是一个sftp实用程序。
答案 0 :(得分:4)
Martin Prikryl(WinSCP的作者)也提供.Net assembly,如果您想切换到PowerShell,这可能是更好的选择。
使用命令行中的参数更新的文档中的.gz
答案 1 :(得分:3)
将cmd.exe
(批处理文件)命令行翻译为PowerShell非常棘手 - 非常棘手,PSv3伪参数中的
引入了--%
, the stop-parsing symbol, :
其目的是允许您将直接之后的所有内容传递给目标程序,除 cmd.exe
- 样式< em> %...%
- 样式环境变量引用 仍然扩展。
注意事项:
--%
必须关注要调用的外部实用程序的名称/路径(它不能首先命令行上的令牌),因此必须使用 PowerShell 定义和引用实用程序可执行文件(路径)本身,如果由[environment]变量传递句法。
--%
必要性(最多)读取行的末尾 [1]
,所以使用行继续字符在多行中传播命令。不受支持。
适用于您的情况,这意味着:
%winscp%
必须翻译为其PowerShell等效项$env:winscp
,后者必须以&
,PowerShell的调用运算符为前缀,这在调用外部命令时是必需的由变量或带引号的字符串指定。& $env:winscp
必须后跟--%
,以确保所有剩余的参数都通过未修改的方式传递(%...%
变量引用的扩展除外)。--%
之后按原样粘贴,但必须在一行。因此,在您的情况下最简单的方法 - 虽然以牺牲必须使用单行为代价 - 是:
# Invoke the command line with --%
# All arguments after --% are used as-is from the original command.
& $env:winscp --% /ini=nul /log=C:\TEMP\winscplog.txt /command "open scp://goofy:changeme@10.61.10.225/ -hostkey=""ssh-rsa 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d""" "put ""%outfile%"" /home/public/somedir/somesubdir/%basename%" "exit"
[1] --%
将所有内容视为传递,直到行尾或下一个未引用的|
出现(以及当前保留的将来使用{ {1}}和&&
),以先到者为准。停在||
允许管道输出
|
命令到另一个命令
即使--%
,PowerShell自己的行继续符,也被视为传递文字。使用`
时,cmd.exe
甚至不参与(除非您明确使用--%
),因此也不能使用其行继续符cmd --% /c ...
。< / SUP>
答案 2 :(得分:2)
每当我必须从PowerShell调用可执行文件时,我总是将参数作为列表传递,如下所示。我也使用单引号,除非我实际上替换变量,在这种情况下我必须使用双引号。
& SomeUtility.exe @('param1','param2',"with$variable")
当参数中有空格时,它会变得有点棘手,因为您可能必须提供引号,以便实用程序可以正确地解析命令。
您的示例更加棘手,因为WinScp需要用引号括起来的/command
参数的参数,以及 double 引号中包含的任何字符串。由于WinScp,所有这些都需要保留。我相信以下内容可行。为了便于阅读,我将参数分解为多行。我还假设您已成功填充了$winscp
,$outfile
和$basename
个变量。
$params = @(
'/ini=nul',
'/log=C:\TEMP\winscplog.txt',
'/command',
'"open scp://goofy:changeme@10.61.10.225/ -hostkey=""ssh-rsa 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d"""',
('"put ""' + $outfile + '"" /home/public/somedir/somesubdir/' + $basename + '"'),
'"exit"'
)
& $winscp $params
注意第五个参数的括号;这是由于那里的字符串连接操作。 (如果没有括号,每个操作数都会单独添加到列表中 - 您可以通过查看$params.Count
来确认。)另请注意,如果您有任何操作数,则需要在日志文件路径周围使用引号把它改成带空格的东西。
答案 3 :(得分:1)
我运行了你的代码(修改后可以使用我自己的服务器),并得到以下日志:
. 2017-03-04 15:32:24.387 Command-line: "C:\Program Files (x86)\WinSCP\WinSCP.exe" /ini=nul /log=C:\TEMP\winscplog.txt /command "open sftp://goofy:***@10.61.10.225/ -hostkey=ssh-rsa" 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d"" exit
. 2017-03-04 15:32:24.388 Time zone: Current: GMT-6, Standard: GMT-6 (Central Standard Time), DST: GMT-5 (Central Daylight Time), DST Start: 3/12/2017, DST End: 11/5/2017
. 2017-03-04 15:32:24.388 Login time: Saturday, March 4, 2017 3:32:24 PM
. 2017-03-04 15:32:24.388 --------------------------------------------------------------------------
. 2017-03-04 15:32:24.388 Script: Retrospectively logging previous script records:
> 2017-03-04 15:32:24.388 Script: open sftp://goofy:***@10.61.10.225/ -hostkey=ssh-rsa
. 2017-03-04 15:32:24.388 --------------------------------------------------------------------------
注意第一行中如何在-hostkey=ssh-rsa
之后立即插入双引号,在最后一行中,-hostkey
参数将从我们预期的内容中截断。
在-hostkey
参数围绕内部双引号加倍后,我能够成功连接:
"/command" 'open sftp://goofy:changeme@10.61.10.225/ -hostkey=""ssh-rsa 2048 d4:1c:1a:4c:c3:60:d5:05:12:02:d2:d8:d6:ae:6c:5d""' `