Рабочий каталог PowerShell Start-Job - PullRequest
24 голосов
/ 08 февраля 2010

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

Использование регистра:

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

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

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

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

Ответы [ 6 ]

22 голосов
/ 30 июня 2013

Есть хорошее решение из раздела комментариев к посту какого-то парня Commenter предлагает использовать параметр Init для настройки рабочего каталога блока скрипта.

function start-jobhere([scriptblock]$block) {
    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block
}
14 голосов
/ 11 февраля 2010

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

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

Ваш скрипт будет выглядеть так:

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

Надеюсь, это поможет.

9 голосов
/ 09 декабря 2016

Чтобы подвести итог проблемы:

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

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

    • Если вы используете PowerShell Core и нацеливаетесь на файл в каталоге current , вы можете использовать следующее, потому что новый ... & синтаксис по умолчанию запускает задание в текущем каталоге :
      emacs RandomFile.txt &

  • Youне может напрямую ссылаться на переменные из текущего сеанса в блоке сценария, передаваемого в Start-Job.

В дополнение к собственной полезности jdmichalответ и полезный ответ Асаварцова , который все еще работает хорошо:

PSv3 представил простой способ ссылки на переменные текущей сессииbles в блоке сценария, который выполняется в другом контексте (в качестве фонового задания или на удаленном компьютере), с помощью области действия $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
6 голосов
/ 20 ноября 2010

попробуйте

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

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

4 голосов
/ 05 декабря 2012

Start-Job - это перебор для того, что вам нужно (запуск команды в фоновом режиме). Используйте Start-Process вместо:

Start-Process -NoNewWindow emacs RandomFile.txt

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

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

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

bg emacs RandomFile.txt

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

2 голосов
/ 17 февраля 2010

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

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