Рабочий Каталог Стартового Задания PowerShell



Можно ли указать рабочий каталог для команды Start-Job?



Пример использования:



Я нахожусь в каталоге и хочу открыть файл, используя Emacs для редактирования. Если я сделаю это напрямую, он будет блокировать PowerShell, пока я не закрою Emacs. Но с помощью Start-Job пытается запустить Emacs из моего домашнего каталога, таким образом, Emacs открывает новый файл вместо того, который я хотел.



Я попытался указать полный путь с помощью $pwd, но переменные в блоке скрипта не разрешаются до тех пор, пока они выполняются в контексте начального задания. Поэтому некоторый способ принудительного разрешения переменных в контексте оболочки также был бы приемлемым ответом на это.



Итак, вот что я попробовал, просто для полноты картины:



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

6 ответов:

Возможным решением было бы создать "Кикер-скрипт":

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 -inputobject $pwd -scriptblock { emacs "$input/RandomFile.txt" }

Здесь $input - предопределенная переменная, которая внутренне принимает значение параметра -inputobject

Чтобы подытожить проблему:

  • Фоновое задание, начатое с Start-Job, не наследует текущее местоположение (рабочий каталог).

    • По умолчанию он равен $HOME\Documents в Windows PowerShell и $HOME в ядре PowerShell (начиная с PSv5.1 / PSv6 alpha).

    • Если вы используете 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 }

Примечание:

  • В этом выпуске GitHub предлагается добавить -WorkingDirectory в командлет Start-Job.

    • 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-это перебор для того, что вам нужно (запуск команды в фоновом режиме). Вместо этого используйте Start-Process :

Start-Process -NoNewWindow emacs RandomFile.txt

В этом подходе нет проблем с текущим каталогом. Я также создал функцию, чтобы сделать это как можно более простым:

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

И тогда вызов становится:

bg emacs RandomFile.txt

Это работает в Windows 7 (Powershell v2).

Просто для полноты картины, вот окончательный сценарий, который я реализовал, основываясь на ответе Филбурта, стиле community-wiki:

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

Comments

    Ничего не найдено.