使用T形三通从另一个外壳运行PowerShell
我想学习从另一个shell或语言执行PowerShell命令,例如Python使用T形三通从另一个外壳运行PowerShell,powershell,cmd,command-line,command-line-interface,Powershell,Cmd,Command Line,Command Line Interface,我想学习从另一个shell或语言执行PowerShell命令,例如Pythonos.system()。我希望实现以下目标: 执行PowerShell命令 将输出同时发送到控制台和文件 返回命令退出代码 假设使用cmd.exe作为调用方环境,我认为这给出了我想要实现的一个想法: powershell -NoProfile -command "& { cat foo.txt | Tee-Object ps-log.txt; exit $LASTEXITCODE }" e
os.system()
。我希望实现以下目标:
powershell -NoProfile -command "& { cat foo.txt | Tee-Object ps-log.txt; exit $LASTEXITCODE }"
echo %errorlevel%
这里有一些问题。首先,我不能在命令中使用引号,例如:
powershell -NoProfile -command "& { cat `"foo bar.txt`" | Tee-Object ps-log.txt; exit $LASTEXITCODE }"
cat
参数似乎是无引号传递的,因此cat
查找“bar.txt”参数
我认为$LASTEXITCODE
很快就会被扩展,也就是说在执行cat
之前
&
不方便使用,因为它不接受包含参数的单个命令行字符串。&
的替代方法是iex
,但是我无法从cmd.exe使用它。事实上:
powershell -NoProfile -command {iex cat foo.txt}
返回:
iex cat foo.txt
从
cmd.exe
,使用以下(-c
是-Command
的缩写):
- 没有理由在传递给
的字符串中使用-Command
——只需使用&{…}
..
- Escape embedded
chars.as“
(PowerShell(Core)7+也接受\”
)”
- 或者,正如所指出的,您可以在传递给
/-Command
的-c
字符串中使用“…”
(单引号),假设不需要'.
- 或者,正如所指出的,您可以在传递给
- 由于该命令仅涉及PowerShell本机命令(在Windows上,
只是的别名),因此未设置cat
,因为它仅反映外部程序的退出代码。而是应用,这是一个布尔值,指示最近执行的管道中的命令是否发出了任何错误$LASTEXITCODE
- 用
对该值求反意味着-not
被转换为$true
,$false
被转换为$false
,这些值被转换为外部整数,$true
映射为$false
,0
映射为$true
1
- 用
powershell -NoProfile -command "cat 'foo bar.txt' | tee ps-log.txt"
除此之外,请看一下mklement0答案中的有用建议。作为旁白:非常感谢。它是有效的(顺便说一句,有一个
}
剩菜),但我不确定幕后发生了什么。我认为,给定命令foo.exe argstring
,Windows cmd将argstring
按原样发送到foo.exe
,由后者决定如何解析字符串。具有Unix根目录的软件将\“
解析为文本”
。PowerShell在这里有点奇怪,因为它广泛地记录了它的backtick转义特性,但它自己的可执行PowerShell.exe不遵循此约定。如果我的猜测是错误的,请纠正我。谢谢你指出拼写错误,@antonio-现在修复了。虽然可能会让人困惑,但PowerShell CLI的行为与常规PowerShell代码不同,以便与Windows上命令行上转义“
字符的最广泛使用的约定保持一致。(在Windows上传递参数的底层体系结构非常不幸。)然而,与此相反,当PowerShell解析外部程序的参数时,基本问题仍然存在,尽管最终采取了一些措施来解决这个问题-请参阅。@antonio:另一种说法是:unescaped“
仅具有CLI的语法功能,需要“
是PowerShell在CLI解析后应执行的源代码的一部分,\”-转义。也就是说,\“
在PowerShell计算命令字符串并具有PowerShell的语法功能时变为”
。请注意,如果您使用的是PowerShell(核心),最好使用”“
在命令行上,因为\”
实际上可以破坏cmd.exe
的语法;例如,powershell-NoProfile-c“\“foo&bar\”
失败,不像pwsh-NoProfile-c““foo&bar”“
谢谢,我确实意识到了这一点,但是,尽管我可以在将变量发送到PowerShell之前展开变量,但参数字符串可以有单引号。所以我需要找到一个转义机制:\“它是foo\”
有效;我找不到等效的\'it's foo\'
工作。
powershell -NoProfile -command "cat 'foo bar.txt' | tee ps-log.txt"