PowerShell 启动作业工作目录

发布于 2024-08-21 12:07:14 字数 410 浏览 15 评论 0原文

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

用例:

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

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

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

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

Is there a way to specify a working directory to the Start-Job command?

Use-case:

I'm in a directory, and I want to open a file using Emacs for editing. If I do this directly, it will block PowerShell until I close Emacs. But using Start-Job attempts to run Emacs from my home directory, thus having Emacs open a new file instead of the one I wanted.

I tried to specify the full path using $pwd, but variables in the script block are not resolved until they're executing in the Start-Job context. So some way to force resolving the variables in the shell context would also be an acceptable answer to this.

So, here's what I've tried, just for completeness:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

迷路的信 2024-08-28 12:07:14

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

function start-jobhere([scriptblock]$block) {
    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}

There is nice solution from comments section of some dude's post. Commenter suggests to use Init parameter to setup working directory of script block.

function start-jobhere([scriptblock]$block) {
    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}
青芜 2024-08-28 12:07:14

更新

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

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

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


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

  • 使用 Start-Job 是否继承当前位置(工作目录)。

    • 在 Windows PowerShell 中默认为 $HOME\Documents,在 PowerShell Core 中默认为 $HOME

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

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

补充jdmichal自己的有用答案asavartsov 的有用答案,仍然有效:

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

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

或者:

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

请参阅 about_Remote_Variables


注意:

  • 此 GitHub 问题报告令人惊讶地无法在传递给 -InitializationScript 的脚本块中使用 $using:,即使它在主脚本中工作块(隐含的 -ScriptBlock 参数)。
    • Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # 失败

Update:

PowerShell [Core] 7.0 brings the following improvements:

  • Background jobs (as well as thread jobs and ForEach-Object -Parallel) now - sensibly - inherit the caller's current (filesystem) location.

  • A new -WorkingDirectory parameter allows you to specify a directory explicitly.


To summarize the problem (applies to Windows PowerShell and PowerShell Core 6.x)

  • A background job started with Start-Job does not inherit the current location (working directory).

    • It defaults to $HOME\Documents in Windows PowerShell, and $HOME in PowerShell Core.

    • If you're using PowerShell Core and you're targeting a file in the current directory, you can use the following, because the new ... & syntax by default runs the job in the current directory:
      emacs RandomFile.txt &

  • You cannot directly reference variables from the current session in a script block passed to Start-Job.

To complement jdmichal's own helpful answer and asavartsov's helpful answer, which still work well:

PSv3 introduced a simple way to reference the current session's variable values in a script block that is executed in a different context (as a background job or on a remote machine), via the $using: scope:

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

Alternatively:

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

See about_Remote_Variables


Note:

  • This GitHub issue reports the surprising inability to use $using: in the script block passed to -InitializationScript, even though it works in the main script block (the implied -ScriptBlock parameter).
    • Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS
浮生面具三千个 2024-08-28 12:07:14

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

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

您的脚本将如下所示:

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

希望这会有所帮助。

A possible solution would be to create a "kicker-script":

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

Your script would look like this:

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

Hope this helps.

川水往事 2024-08-28 12:07:14

试试这个

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

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

try this

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

Here $input is predefined variable that internally take the value of -inputobject parameter

離人涙 2024-08-28 12:07:14

Start-Job 对于您所需要的(在后台运行命令)来说是一种矫枉过正。使用 Start-Process 代替:

Start-Process -NoNewWindow emacs RandomFile.txt

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

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

然后调用变为:

bg emacs RandomFile.txt

这适用于 Windows 7 (Powershell v2)。

Start-Job is an overkill for what you need (running a command in the background). Use Start-Process instead:

Start-Process -NoNewWindow emacs RandomFile.txt

There are no issue with the current directory in this approach. I have also created a function to make this as simple as possible:

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

and then the invocation becomes:

bg emacs RandomFile.txt

This works on Windows 7 (Powershell v2).

橘虞初梦 2024-08-28 12:07:14

为了完整起见,这是我根据 Filburt 的答案(社区维基风格)实现的最终脚本:

function Start-Emacs ( [string]$file )
{
    Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}

Just for completeness, here's the final script I implemented based on Filburt's answer, community-wiki style:

function Start-Emacs ( [string]$file )
{
    Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文