Domanda

C'è un modo per specificare una directory di lavoro al comando Start-Job?

Usa-caso:

Sono in una directory, e voglio aprire un file utilizzando Emacs per la modifica. Se faccio questo direttamente, bloccherà PowerShell fino a quando chiudo Emacs. Ma usando Start-Job tenta di eseguire Emacs dalla mia home directory, avendo così Emacs aprire un nuovo file invece di quello che volevo.

Ho cercato di specificare il percorso completo utilizzando $ pwd, ma variabili nel blocco di script non vengono risolti fino a quando sono in esecuzione nel contesto Start-Job. Quindi un modo per forzare risolvere le variabili del contesto shell potrebbe anche essere una risposta accettabile per questo.

Quindi, ecco quello che ho provato, solo per completezza:

Start-Job { emacs RandomFile.txt }
Start-Job { emacs "$pwd/RandomFile.txt" }
È stato utile?

Soluzione

Una possibile soluzione potrebbe essere quella di creare un "kicker-script":

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

Lo script sarebbe simile a questa:

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

Spero che questo aiuti.

Altri suggerimenti

Per riassumere il problema:

  • un processo in background è iniziato con Start-Job non ereditano la (directory di lavoro) posizione corrente.

    • Il valore predefinito è $HOME\Documents in Windows PowerShell, e $HOME in PowerShell core (come di PSv5.1 / PSv6 alfa).

    • Se stai usando PowerShell Nucleo e che stai targeting un file nel corrente di directory, è possibile utilizzare il in seguito, perché il nuova sintassi ... & per default viene eseguito il lavoro nella corrente directory :
      emacs RandomFile.txt &

  • Non puoi direttamente variabili di riferimento della corrente sessione in un blocco di script passato a Start-Job.

Per completare di jdmichal propria risposta utile e di asavartsov risposta utile , che ancora funzionano bene:

PSv3 ha introdotto un modo semplice per fare riferimento al corrente variabili di sessione in un blocco di script che viene eseguito in un contesto diverso (come un processo in background o su una macchina remota), attraverso l'ambito $using::

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

In alternativa:

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

Nota:

  • Questo problema GitHub propone l'aggiunta di un -WorkingDirectory al cmdlet Start-Job.

    • Start-Job -WorkingDirectory $PWD { emacs RandomFile.txt } # WISHFUL THINKING
  • Questo problema GitHub rapporti l'incapacità sorprendente di utilizzare $using: nello script blocco passato a -InitializationScript, anche se funziona nel blocco di script principale (il parametro -ScriptBlock implicita).

    • Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS

provare questo

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

Qui $input è variabile predefinita che prendono internamente il valore del parametro -inputobject

Start-Job è un eccessivo per quello che vi serve (l'esecuzione di un comando in background). Utilizza Start-Process , invece:

Start-Process -NoNewWindow emacs RandomFile.txt

Non ci sono alcun problema con la directory corrente in questo approccio. Ho creato anche una funzione per rendere questo il più semplice possibile:

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

e quindi l'invocazione diventa:

bg emacs RandomFile.txt

Questo funziona su Windows 7 (PowerShell v2).

Solo per completezza, ecco lo script finale ho implementato in base alla risposta del Filburt, stile comunità-wiki:

function Start-Emacs ( [string]$file )
{
    Start-Job -ArgumentList "$pwd\$file" { emacs $args[0] }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top