题
有没有办法为 Start-Job 命令指定工作目录?
用例:
我在一个目录中,我想使用 Emacs 打开一个文件进行编辑。如果我直接执行此操作,它将阻止 PowerShell,直到我关闭 Emacs。但是使用 Start-Job 尝试从我的主目录运行 Emacs,从而使 Emacs 打开一个新文件而不是我想要的文件。
我尝试使用 $pwd 指定完整路径,但脚本块中的变量只有在 Start-Job 上下文中执行时才会解析。因此,强制解析 shell 上下文中的变量的某种方法也是一个可以接受的答案。
所以,为了完整性,这是我尝试过的:
Start-Job { emacs RandomFile.txt }
Start-Job { emacs "$pwd/RandomFile.txt" }
解决方案
一个可能的解决方案是创建一个“踢球者脚本”:
Start-Job -filepath .\emacs.ps1 -ArgumentList $workingdir, "RandomFile.txt"
您的脚本应该是这样的:
Set-Location $args[0]
emacs $args[1]
希望这有助于。
其他提示
有从评论部分很好的解决方案有些花花公子的帖子。评论者建议使用Init
参数脚本块的设置工作目录。
function start-jobhere([scriptblock]$block) {
Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}
总结一下问题:
后台作业开始于
Start-Job
做 不是 继承当前位置(工作目录)。它默认为
$HOME\Documents
在 Windows PowerShell 中,以及$HOME
在 PowerShell Core 中(从 PSv5.1 / PSv6 alpha 开始)。如果您正在使用 电源外壳 核 并且您的目标文件是 当前的 目录,您可以使用以下内容,因为 新的
... &
默认情况下,语法运行作业 当前的 目录:
emacs RandomFile.txt &
你不能 直接地 参考变量来自 当前的 脚本块中的会话传递给
Start-Job
.
来补充 jdmichal 自己的有用答案 和 阿萨瓦尔佐夫的有用答案, ,仍然运行良好:
PSv3引入了一种简单的方法来引用 当前的 脚本块中的会话变量在不同的上下文中执行(作为后台作业或在远程计算机上),通过 $using:
范围:
Start-Job { Set-Location $using:PWD; emacs RandomFile.txt }
或者:
Start-Job { emacs $using:PWD/RandomFile.txt }
笔记:
这个 GitHub 问题 建议添加一个
-WorkingDirectory
到Start-Job
cmdlet。Start-Job -WorkingDirectory $PWD { emacs RandomFile.txt } # WISHFUL THINKING
这个 GitHub 问题 报告令人惊讶地无法使用
$using:
在传递给的脚本块中-InitializationScript
, ,即使它在主脚本块中工作(隐含的-ScriptBlock
范围)。Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS
尝试此
Start-Job -inputobject $pwd -scriptblock { emacs "$input/RandomFile.txt" }
下面$input
是预定义的变量,内服-inputobject
参数的值
开始,工作是你所需要的矫枉过正(在后台运行一个命令)。使用启动过程强>代替:
Start-Process -NoNewWindow emacs RandomFile.txt
有与本办法的当前目录中没有问题。我还创建了一个函数,使这个尽可能简单:
function bg() {Start-Process -NoNewWindow @args}
和然后调用变为:
bg emacs RandomFile.txt
此可以在Windows 7(Powershell的V2)。
只是为了完整性,这里是我实现了基于Filburt的答案最终脚本,社区wiki模式:
function Start-Emacs ( [string]$file )
{
Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}