PowerShell 启动作业工作目录
有没有办法为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
一些家伙的评论部分有一个很好的解决方案发布。评论者建议使用
Init
参数来设置脚本块的工作目录。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.更新:
PowerShell [Core] 7.0 带来了以下改进:
后台作业(以及线程作业和
ForEach- Object -Parallel
)现在 - 明智地 - 继承调用者的当前(文件系统)位置。新的
-WorkingDirectory
参数允许您显式指定目录。总结问题(适用于 Windows PowerShell 和 PowerShell Core 6.x)
使用
Start-Job
是否不继承当前位置(工作目录)。在 Windows PowerShell 中默认为
$HOME\Documents
,在 PowerShell Core 中默认为$HOME
。如果您使用的是 PowerShell Core,并且您的目标是当前目录中的文件,则可以使用以下,因为默认情况下新
... &
语法在当前目录中运行作业:emacs RandomFile.txt &
您不能在传递给
Start- 的脚本块中直接引用当前会话中的变量作业
。补充jdmichal自己的有用答案和asavartsov 的有用答案,仍然有效:
PSv3 引入了一种简单的方法来引用脚本块中当前会话的变量值,该脚本块在不同的上下文中执行(作为后台作业或在远程计算机上),通过
$using:
范围:或者:
请参阅
about_Remote_Variables
注意:
-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:Alternatively:
See
about_Remote_Variables
Note:
$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
一个可能的解决方案是创建一个“踢球脚本”:
您的脚本将如下所示:
希望这会有所帮助。
A possible solution would be to create a "kicker-script":
Your script would look like this:
Hope this helps.
试试这个
这里
$input
是预定义变量,内部采用-inputobject
参数的值try this
Here
$input
is predefined variable that internally take the value of-inputobject
parameterStart-Job 对于您所需要的(在后台运行命令)来说是一种矫枉过正。使用 Start-Process 代替:
此方法中的当前目录没有问题。我还创建了一个函数来使其尽可能简单:
然后调用变为:
这适用于 Windows 7 (Powershell v2)。
Start-Job is an overkill for what you need (running a command in the background). Use Start-Process instead:
There are no issue with the current directory in this approach. I have also created a function to make this as simple as possible:
and then the invocation becomes:
This works on Windows 7 (Powershell v2).
为了完整起见,这是我根据 Filburt 的答案(社区维基风格)实现的最终脚本:
Just for completeness, here's the final script I implemented based on Filburt's answer, community-wiki style: