32

有没有办法为 Start-Job 命令指定工作目录?

用例:

我在一个目录中,我想使用 Emacs 打开一个文件进行编辑。如果我直接这样做,它将阻止 PowerShell,直到我关闭 Emacs。但是使用 Start-Job 会尝试从我的主目录运行 Emacs,从而让 Emacs 打开一个新文件而不是我想要的文件。

我尝试使用 $pwd 指定完整路径,但脚本块中的变量在它们在 Start-Job 上下文中执行之前不会被解析。因此,某种强制解析 shell 上下文中的变量的方法也是可以接受的答案。

所以,这是我尝试过的,只是为了完整性:

Start-Job { emacs RandomFile.txt }
Start-Job { emacs "$pwd/RandomFile.txt" }
4

6 回答 6

35

一些家伙的帖子的评论部分有很好的解决方案。评论者建议使用Init参数来设置脚本块的工作目录。

function start-jobhere([scriptblock]$block) {
    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}
于 2013-06-30T09:32:29.517 回答
16

一个可能的解决方案是创建一个“踢球脚本”:

Start-Job -filepath .\emacs.ps1 -ArgumentList $workingdir, "RandomFile.txt"

您的脚本将如下所示:

Set-Location $args[0]
emacs $args[1]

希望这可以帮助。

于 2010-02-11T18:08:08.990 回答
16

更新

PowerShell [Core] 7.0带来了以下改进

  • 后台作业(以及线程作业和ForEach-Object -Parallel)现在 - 明智地 - 继承调用者的当前(文件系统)位置。

  • 一个新-WorkingDirectory参数允许您显式指定目录。


总结问题(适用于Windows PowerShellPowerShell Core 6.x

  • 开始的后台作业Start-Job不会继承当前位置(工作目录)。

    • 它默认$HOME\Documents在 Windows PowerShell 和$HOMEPowerShell Core 中。

    • 如果您使用的是PowerShell Core,并且您的目标是当前目录中的文件,则可以使用以下命令,因为默认情况下... &语法会在当前目录中运行作业:
      emacs RandomFile.txt &

  • 您不能在传递给的脚本块中直接引用当前会话中的变量Start-Job

为了补充jdmichal 自己的有用答案asavartsov 的有用答案,它们仍然很好用:

PSv3 引入了一种简单的方法,可以通过作用域在不同上下文(作为后台作业或远程机器上)执行的脚本块中引用当前$using:会话的变量值:

Start-Job { Set-Location $using:PWD; emacs RandomFile.txt }

或者:

Start-Job { emacs $using:PWD/RandomFile.txt }

about_Remote_Variables


笔记:

  • 这个 GitHub 问题报告了令人惊讶的无法$using:在传递给的脚本块中使用-InitializationScript,即使它在主脚本块(隐含-ScriptBlock参数)中工作。
    • Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS
于 2016-12-09T06:43:01.527 回答
7

试试这个

Start-Job -inputobject $pwd -scriptblock { emacs "$input/RandomFile.txt" }

$input是内部采用-inputobject参数值的预定义变量

于 2010-11-20T06:19:34.477 回答
5

Start-Job 对你需要的东西来说太过分了(在后台运行命令)。使用Start-Process代替:

Start-Process -NoNewWindow emacs RandomFile.txt

在这种方法中,当前目录没有问题。我还创建了一个函数来使其尽可能简单:

function bg() {Start-Process -NoNewWindow @args}

然后调用变为:

bg emacs RandomFile.txt

这适用于 Windows 7 (Powershell v2)。

于 2012-12-05T17:25:30.670 回答
2

只是为了完整起见,这是我根据 Filburt 的回答实现的最终脚本,community-wiki 风格:

function Start-Emacs ( [string]$file )
{
    Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}
于 2010-02-17T18:51:05.657 回答