2010-02-08 6 views
21

Existe-t-il un moyen de spécifier un répertoire de travail à la commande Start-Job?Répertoire de travail de démarrage de PowerShell

cas d'utilisation:

Je suis dans un répertoire, et je veux ouvrir un fichier en utilisant Emacs pour l'édition. Si je le fais directement, il bloquera PowerShell jusqu'à ce que je ferme Emacs. Mais en utilisant Start-Job tente d'exécuter Emacs à partir de mon répertoire personnel, Emacs ouvre donc un nouveau fichier au lieu de celui que je voulais.

J'ai essayé de spécifier le chemin complet en utilisant $ pwd, mais les variables du bloc de script ne sont pas résolues tant qu'elles ne sont pas exécutées dans le contexte de démarrage. Donc, un moyen de forcer la résolution des variables dans le contexte shell serait également une réponse acceptable à cela.

Alors, voici ce que j'ai essayé, juste pour être complet:

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

Répondre

13

Une solution possible serait de créer un "kick-script":

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

Votre script ressemblerait ceci:

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

Espérons que cela aide.

+1

Cela a très bien fonctionné. Le -ArgumentList est exactement le genre de chose que je cherchais. – jdmichal

+0

Gardez à l'esprit que cela ne fonctionnera que si $ workingdir ne contient aucun espace ou autre caractère spécial. – DiscoInfiltrator

+0

@DiscoInfiltrator: Passer juste '$ workingdir' fonctionne correctement dans PowerShell, même avec des espaces intégrés et d'autres métacaractères shell (vous pensez probablement à des shells de type POSIX); vérifier avec '$ dir = 'C: \ Program Files \'; function foo() {set-location $ args [0]}; foo $ dir'. – mklement0

2

Juste pour être complet, voici le script final j'ai mis en fonction de la réponse de Filburt, style-wiki communautaire:

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

essayer cette

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

Ici $input est variable prédéfinie qui prennent en interne la valeur de -inputobject paramètre

4

Start-Job est une surcharge pour ce dont vous avez besoin (exécution d'une commande en arrière-plan). Utilisez Start-Process à la place:

Start-Process -NoNewWindow emacs RandomFile.txt 

Il n'y a pas de problème avec le répertoire en cours dans cette approche. J'ai aussi créé une fonction pour ce aussi simple que possible:

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

et l'invocation devient:

bg emacs RandomFile.txt 

Cela fonctionne sous Windows 7 (Powershell v2).

+0

Mais Start-Process persiste après la fermeture du terminal? – CMCDragonkai

17

Il y a une bonne solution de comments section of some dude's post. Commenter suggère d'utiliser le paramètre Init pour configurer le répertoire de travail du bloc de script.

function start-jobhere([scriptblock]$block) { 
    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block 
} 
+0

++ pour la solution la plus générique: aucun script d'assistance requis, aucun argument d'entrée que le bloc de script d'arrière-plan doit connaître et gérer. – mklement0

+0

cela devrait avoir des guillemets autour de $ pwd pour gérer les espaces dans le chemin – ghostbust555

+0

@ ghostbust555 est correct, des guillemets simples sont nécessaires car ce n'est pas une référence de variable mais une extension de variable dans une chaîne. – Sander

3

Pour résumer le problème:

  • Un travail de fond a commencé avec Start-Job ne fait pas possèdes l'emplacement actuel (répertoire de travail).

    • par défaut à $HOME\Documents dans Windows PowerShell et $HOME dans PowerShell de base (en PSv5.1/PSv6 alpha).

    • Si vous utilisez PowerShell de base et vous ciblez un fichier dans le répertoire courant , vous pouvez utiliser ce qui suit, car la nouvelle syntaxe ... & par défaut exécute le travail dans le courant répertoire:
      emacs RandomFile.txt &

  • Vous ne pouvez pas directement les variables de référence de en cours session dans un bloc de script passé à Start-Job.

Pour compléter jdmichal's own helpful answer et asavartsov's helpful answer, qui fonctionnent encore bien:

PSV3 introduit un moyen simple pour référencer les courants les variables de session dans un bloc de script qui est exécuté dans un contexte différent (en arrière-plan travail ou sur une machine distante), par l'intermédiaire de la portée $using::

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

variante:

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

Note:

  • This GitHub issue propose d'ajouter un -WorkingDirectory à l'applet de commande Start-Job.

    • Start-Job -WorkingDirectory $PWD { emacs RandomFile.txt } # WISHFUL THINKING
  • This GitHub issue signale l'incapacité étonnante à utiliser $using: dans le bloc de script est passé à -InitializationScript, même si cela fonctionne dans le bloc principal de script (le paramètre -ScriptBlock implicite).

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