我有一个python脚本吐出JSON我想用ConvertFrom-Json
捕获。不幸的是,这个脚本要求我在运行之前cd到不同的目录。什么是惯用的powershell方式呢?
这有效:
$q = powershell.exe -Command "cd some\other\dir; python JsonMaker.py | ConvertFrom-Json"
就像这样:
$cwd=Get-Location
cd some\other\dir
$q=python JsonMaker.py | ConvertFrom-Json
cd "$cwd"
但是改变当前的工作目录对我来说似乎很冒险 - 如果python脚本输出格式错误的JSON,我会留在some\other\dir
吗?
在unix shell脚本世界中,我显然做了类似
的事情(cd some/other/dir && python JsonMaker.py) | commandThatUsesJson
或使用$(cd some/other/dir && python JsonMaker.py)
阅读输入内容。但是,在unix子壳中便宜。在powershell中,我发现启动子shell有明显的延迟。
Powershell长期用户采用的方法是什么?
答案 0 :(得分:1)
我可能会使用pushd / popd:
pushd some\other\dir
$q=python JsonMaker.py | ConvertFrom-Json
popd
答案 1 :(得分:1)
你的脚本对我来说很好看。除非ConvertFrom-Json
抛出终止异常(我认为不会这样),否则脚本将继续,并且您的cd $cwd
行会重新回复。
你也可以使用Push-/Pop-Location
,但它基本上只是一种“漂亮”的方式来做你已经拥有的东西。实施例
#Save location
Push-Location
#Script
Set-Location some\other\dir
python JsonMaker.py | ConvertFrom-Json
#Return to previous location
Pop-Location
答案 2 :(得分:0)
python.exe JsonMaker.py
作为子进程运行。对子进程中当前目录所做的更改不会影响父进程。 ConvertFrom-Json
也不会影响当前目录。它将JSON字符串转换为表示JSON数据的对象,如果JSON字符串格式错误,则会抛出(非终止)错误。
如果您想要安全起见,请在try
块中运行转换,并将该语句放在该块之后的临时工作目录中:
try {
$q = python JsonMaker.py | ConvertFrom-Json
} catch {
# error handling (optional)
}
cd "$cwd"
或finally
条款:
try {
$q = python JsonMaker.py | ConvertFrom-Json
} catch {
# error handling (optional)
} finally {
cd "$cwd"
}
正如其他人已经提到的,我会使用Push-Location
和Pop-Location
(或他们的别名pushd
和popd
)作为更改为不同工作的简单方法目录并返回原始目录。 cmdlet的工作方式类似于Unix shell命令pushd
和popd
。
我还建议将扩展名添加到可执行文件名中(以避免无意中运行具有相同基本名称的不同可执行文件(例如python.cmd
或python.com
)并使用call operator( &
)。在新的powershell.exe
进程中运行命令是没有必要的,并且还只返回从JSON字符串而不是对象本身创建的对象的字符串表示,这可能不是什么你想要的。
修改后的代码:
Push-Location 'D:\some\other\dir'
try {
$q = & python.exe JsonMaker.py | ConvertFrom-Json
} catch {
# error handling (optional)
} finally {
Pop-Location
}
或者像这样,如果你想有条件地运行python脚本只有在改变目录成功时(因此完全模仿&&
的行为):
try {
Push-Location 'D:\some\other\dir' -ErrorAction Stop
$q = & python.exe JsonMaker.py | ConvertFrom-Json
} catch {
# error handling (optional)
} finally {
Pop-Location
}