Ответ 1
Возможным решением было бы создать "kicker- script":
Start-Job -filepath .\emacs.ps1 -ArgumentList $workingdir, "RandomFile.txt"
Ваш script будет выглядеть так:
Set-Location $args[0]
emacs $args[1]
Надеюсь, что это поможет.
Есть ли способ указать рабочий каталог для команды Start-Job?
Использование случая:
Я в директории, и я хочу открыть файл с помощью Emacs для редактирования. Если я сделаю это напрямую, он заблокирует PowerShell, пока я не закрою Emacs. Но использование Start-Job пытается запустить Emacs из моего домашнего каталога, поэтому Emacs открывает новый файл вместо того, который мне нужен.
Я попытался указать полный путь с помощью $pwd, но переменные в блоке script не будут разрешены до тех пор, пока они не будут выполняться в контексте Start-Job. Таким образом, приемлемым для этого был бы также способ принудительного решения переменных в контексте оболочки.
Итак, вот что я пробовал, просто для полноты:
Start-Job { emacs RandomFile.txt }
Start-Job { emacs "$pwd/RandomFile.txt" }
Возможным решением было бы создать "kicker- script":
Start-Job -filepath .\emacs.ps1 -ArgumentList $workingdir, "RandomFile.txt"
Ваш script будет выглядеть так:
Set-Location $args[0]
emacs $args[1]
Надеюсь, что это поможет.
Есть хорошее решение из раздел комментариев какого-то сообщения чувака. Commenter предлагает использовать параметр Init
для настройки рабочего каталога блока script.
function start-jobhere([scriptblock]$block) {
Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}
попробуйте это
Start-Job -inputobject $pwd -scriptblock { emacs "$input/RandomFile.txt" }
Здесь $input
- предопределенная переменная, которая внутренне принимает значение параметра -inputobject
Start-Job - это избыток для того, что вам нужно (выполнение команды в фоновом режиме). Вместо этого используйте Start-Process:
Start-Process -NoNewWindow emacs RandomFile.txt
В этом подходе нет проблемы с текущим каталогом. Я также создал функцию, которая сделает это максимально простым:
function bg() {Start-Process -NoNewWindow @args}
а затем вызов будет:
bg emacs RandomFile.txt
Это работает в Windows 7 (Powershell v2).
Просто для полноты, здесь окончательный script я реализовал на основе ответа Filburt, стиль community-wiki:
function Start-Emacs ( [string]$file )
{
Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}
Подводя итог проблеме:
Фоновая работа, начинающаяся с Start-Job
, не наследует текущее местоположение (рабочий каталог).
По умолчанию он равен $HOME\Documents
в Windows PowerShell и $HOME
в PowerShell Core (с PSv5.1/PSv6 alpha).
Если вы используете PowerShell Core, и вы нацеливаете файл в текущем каталоге, вы можете использовать следующее, потому что синтаксис new ... &
по умолчанию запускает задание в текущем каталоге: emacs RandomFile.txt &
Вы не можете напрямую ссылаться на переменные из текущего сеанса в блоке script, переданном на Start-Job
.
Чтобы дополнить jdmichal собственный полезный ответ и асавартовский полезный ответ, который все еще хорошо работает:
PSv3 представил простой способ ссылки на текущие переменные сеанса в блоке script, который выполняется в другом контексте (в качестве фонового задания или на удаленной машине) через область $using:
:
Start-Job { Set-Location $using:PWD; emacs RandomFile.txt }
В качестве альтернативы:
Start-Job { emacs $using:PWD/RandomFile.txt }
Примечание:
Эта проблема GitHub предлагает добавить командную строку -WorkingDirectory
в командлет Start-Job
.
Start-Job -WorkingDirectory $PWD { emacs RandomFile.txt } # WISHFUL THINKING
Эта проблема GitHub сообщает об удивительной неспособности использовать $using:
в блоке script, переданном в -InitializationScript
, даже если он работает в основном блоке script (подразумеваемый параметр -ScriptBlock
).
Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS