Mic*_*ter 4 syntax powershell winscp
我在 .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"
Run Code Online (Sandbox Code Playgroud)
我试图将其复制到这样的 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"
Run Code Online (Sandbox Code Playgroud)
当我运行 .bat 脚本时,文件将上传。
当我运行 .ps1 脚本时,我得到 Host key does not match configured key ssh-rsa
我怀疑我没有在 powershell 中正确格式化命令,并且在 winscp 看到它时主机密钥已经损坏。
我检查了日志,显示的只是来自主机的主机密钥。它没有显示我正在使用的密钥。我通过更改我的主机并注意到它没有出现在日志中来确认这一点。我比较了 .bat 和 .ps1 之间的日志,不同之处在于 ps1 以上述错误终止。
winscp 是一个 sftp 实用程序。
笔记:
在这种情况下,JamesQMurphy 的有用答案是最佳解决方案。
这个答案通常讨论翻译为cmd.exe
PowerShell编写的命令行。
平移cmd.exe
(批处理文件)的命令行到PowerShell是棘手-如此棘手,即在PSv3伪参数
--%
,该停止解析符号,被介绍:
它的目的是让你通过后到来的一切--%
作为,就是通过对目标程序,从而控制确切的报价-除非是cmd.exe
风格%...%
样式的环境变量的引用都还在扩大通过PowerShell的[1] 。
然而,--%
它有许多严重的限制——下面讨论——它的用处仅限于 Windows,所以它应该被认为是最后的手段;
另一种方法是使用PSv3+Native
模块(Install-Module Native
从PSv5+ 中的PowerShell Gallery安装),它提供了两个命令,可以在内部补偿 PowerShell 的所有参数传递和cmd.exe
参数解析怪癖:
Function ie
,您可以将其添加到对外部程序的任何调用之前,包括cmd.exe
,允许您仅使用PowerShell的 syntax_,而不必担心参数传递问题;例如:
# Without `ie`, this command would malfunction.
'a"b' | ie findstr 'a"b'
Run Code Online (Sandbox Code Playgroud)
Function ins
( Invoke-NativeShell
) 函数允许您重用按原样编写的cmd.exe
命令行,作为单个字符串传递;与 不同--%
,这还允许您通过 PowerShell可扩展字符串( )在命令行中嵌入PowerShell变量和表达式:"..."
# Simple, verbatim cmd.exe command line.
ins 'ver & whoami'
# Multi-line, via a here-string.
ins @'
dir /x ^
c:\
'@
# With up-front string interpolation to embed a PowerShell var.
$var='c:\windows'; ins "dir /x `"$var`""
Run Code Online (Sandbox Code Playgroud)
--%
--%
必须遵循要调用的外部实用程序的名称/路径(它不能是命令行上的第一个标记),以便实用程序可执行文件(路径)本身,如果通过 [environment] 变量传递,则必须定义和引用使用PowerShell语法。
--%
仅支持一个命令,该命令不加引号|
,||
或&&
在同一行(如果存在)隐式结束;这允许您将这样的命令通过管道/链接到/与其他命令。
但是,不支持使用;
in order 无条件地将另一个命令放在同一行上;将通过逐字传递。;
--%
读取(最多)到行尾,因此使用行继续符将命令扩展到多行。不支持。[2]
除了%...%
环境变量引用,您不能在命令中嵌入任何其他动态元素;也就是说,您不能使用常规 PowerShell 变量引用或表达式。
%
字符%%
(您可以在批处理文件中执行的方式);如果引用已定义的环境变量,则标记总是会扩展(如果不是,则标记按原样传递)。%<name>%
<name>
除了%...%
环境变量引用,您不能在命令中嵌入任何其他动态元素;也就是说,您不能嵌入常规 PowerShell 变量引用或表达式。
您不能使用流重定向(例如,>file.txt
),因为它们是逐字传递的,作为目标命令的参数。
| Set-Content file.txt
来解决该问题,但对于stderr输出没有直接的 PowerShell 解决方法。cmd
调用命令,则可以让cmd
处理 (stderr) 重定向(例如,cmd --% /c nosuch 2>file.txt
)应用于您的案例,这意味着:
%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"
Run Code Online (Sandbox Code Playgroud)
[1] 请注意,尽管cmd.exe
-like 语法--%
也适用于 PowerShell Core(macOS、Linux)中的类 Unix平台,但在那里的用途非常有限:与诸如bash
那里的本机 shell 不同,--%
仅适用于双引号字符串( "..."
); 例如,bash --% -c "hello world"
工作,但bash --% -c 'hello world'
不支持-并且不支持通常的 shell 扩展,特别是 globbing - 请参阅此 GitHub 问题。
[2] Even `
,PowerShell 自己的行继续符,被视为传递文字。cmd.exe
当您使用时甚至不涉及--%
(除非您明确使用cmd --% /c ...
),因此它的行继续符^
, 也不能使用。
归档时间: |
|
查看次数: |
1044 次 |
最近记录: |