2010-02-08 11 views
21

¿Hay alguna forma de especificar un directorio de trabajo para el comando de inicio de tareas?Directorio de trabajo de inicio de tareas de PowerShell

de casos de uso:

Estoy en un directorio, y quiero abrir un archivo con Emacs para su edición. Si hago esto directamente, bloqueará PowerShell hasta que cierre Emacs. Pero el uso de Start-Job intenta ejecutar Emacs desde mi directorio personal, lo que hace que Emacs abra un archivo nuevo en lugar del que yo quería.

Intenté especificar la ruta completa usando $ pwd, pero las variables en el bloque de script no se resuelven hasta que se ejecutan en el contexto de Start-Job. Entonces, alguna forma de forzar la resolución de las variables en el contexto del shell también sería una respuesta aceptable a esto.

Por lo tanto, esto es lo que he intentado, simplemente para la corrección:

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

Respuesta

13

Una posible solución sería la creación de un "kicker-script":

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

Su guión se vería como esto:

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

Espero que esto ayude.

+1

Esto funcionó muy bien. The-ArgumentList es exactamente el tipo de cosa que estaba buscando. – jdmichal

+0

Tenga en cuenta que esto solo funcionará si '$ workingdir' no contiene espacios u otros caracteres especiales. – DiscoInfiltrator

+0

@DiscoInfiltrator: pasar solo '$ workingdir' funciona bien en PowerShell, incluso con espacios incrustados y otros metacaracteres de shell (probablemente esté pensando en shells similares a POSIX); verificar con '$ dir = 'C: \ Archivos de programa \'; función foo() {set-location $ args [0]}; foo $ dir'. – mklement0

2

simplemente para la corrección, aquí está el guión final he implementado basado en el estilo de respuesta, la comunidad wiki de Filburt:

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

probar esto

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

Aquí $input es variable predefinida que ingiera el valor de -inputobject parámetro

4

Start-Job es un exceso de lo que necesita (ejecutando un comando en el fondo). Utilice Start-Proceso lugar:

Start-Process -NoNewWindow emacs RandomFile.txt 

No hay problema con el directorio actual en este enfoque. También he creado una función para hacer esto tan simple como sea posible:

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

y luego se convierte en la invocación:

bg emacs RandomFile.txt 

Esto funciona en Windows 7 (Powershell v2).

+0

¿Pero el proceso de inicio persiste después de que se cierra el terminal? – CMCDragonkai

17

Hay una buena solución de comments section of some dude's post. El comentarista sugiere utilizar el parámetro Init para configurar el directorio de trabajo del bloque de scripts.

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

++ para la solución más genérica: no se necesita script auxiliar, no hay ningún argumento de entrada que el bloque de script de fondo necesite conocer y manejar. – mklement0

+0

esto debería tener comillas alrededor de $ pwd para manejar espacios en la ruta – ghostbust555

+0

@ ghostbust555 es correcto, se necesitan comillas simples porque no es una referencia de variable sino una expansión variable en una cadena. – Sander

3

Para resumir el problema:

  • Un trabajo de fondo empezó con Start-Job hace no heredan la ubicación actual (directorio de trabajo).

    • Su valor predeterminado es $HOME\Documents en Windows PowerShell, y $HOME en PowerShell Core (como de PSv5.1/PSV6 alfa).

    • Si está utilizando PowerShell Core y que está dirigida a un archivo en el directorio actual, puede utilizar la siguiente, debido a que la nueva ... & sintaxis por defecto ejecuta el trabajo en el actual directorio de:
      emacs RandomFile.txt &

  • no se puede directamente variables de referencia de la actual sesión en un bloque de script pasado a Start-Job.

Para complementar jdmichal's own helpful answer y asavartsov's helpful answer, que todavía funciona bien:

PSV3 introdujo una forma sencilla de hacer referencia a los variables actuales de sesión en un bloque de script que se ejecuta en un contexto diferente (como un fondo puesto de trabajo o en una máquina remota), a través del alcance $using::

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

Alternativamente:

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

Nota:

  • This GitHub issue propone la adición de un -WorkingDirectory al cmdlet Start-Job.

    • Start-Job -WorkingDirectory $PWD { emacs RandomFile.txt } # WISHFUL THINKING
  • This GitHub issue informa de la imposibilidad de usar sorprendente $using: en el bloque de script pasado a -InitializationScript, a pesar de que trabaja en el bloque de script principal (la implícita -ScriptBlock parámetro).

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