2011-01-18 29 views
102

Tengo un script de PowerShell que hace algunas cosas utilizando el directorio actual del script. Entonces, cuando esté dentro de ese directorio, ejecutar .\script.ps1 funciona correctamente.PowerShell: Ejecute el comando desde el directorio de scripts

Ahora quiero llamar a esa secuencia de comandos desde un directorio diferente sin cambiar el directorio de referencia de la secuencia de comandos. Así que quiero llamar al ..\..\dir\script.ps1 y aún quiero que ese script se comporte como se llamó desde dentro de su directorio.

¿Cómo hago eso o cómo modifico una secuencia de comandos para que pueda ejecutarse desde cualquier directorio?

Respuesta

146

¿Quiere decir que desea la ruta del script para que pueda hacer referencia a un archivo al lado del script? Pruebe esto:

$scriptpath = $MyInvocation.MyCommand.Path 
$dir = Split-Path $scriptpath 
Write-host "My directory is $dir" 

Puede obtener mucha información de $ MyInvocation y sus propiedades.

Si desea hacer referencia a un archivo en el directorio de trabajo actual, puede utilizar Resolve-Path o Get-ChildItem:

$filepath = Resolve-Path "somefile.txt" 

EDITAR (basado en el comentario de la OP):

# temporarily change to the correct folder 
Push-Location $folder 

# do stuff, call ant, etc 

# now back to previous directory 
Pop-Location 

Probablemente haya otras maneras de lograr algo similar usando Invoke-Command también.

+1

Hmm, bien, tal vez debería haber sido un poco más claro sobre mi guión. En realidad, es un script que llama 'hormiga' con algunos parámetros. Así que tengo que llamar a 'ant' desde esa carpeta para asegurarme de que encuentre el archivo de configuración correctamente. Idealmente, estoy buscando algo para cambiar temporalmente el directorio de ejecución localmente dentro de ese script. – poke

+3

Ah, entonces en ese caso querrá 'Push-Location' y' Pop-Location' – JohnL

+4

teniendo cuidado con eso, $ MyInvocation es sensible al contexto, usualmente hago $ ScriptPath = (Get-Variable MyInvocation -Scope Script) .Value.MyCommand .Ruta que funciona desde cualquier tipo de anidamiento o función –

27

Si está llamando a aplicaciones nativas, debe preocuparse por [Environment]::CurrentDirectory y no por el directorio actual $PWD de PowerShell. Por algún motivo, me escapa, PowerShell does not set the process' current working directory when you Set-Location or Push-Location, por lo que debe asegurarse de hacerlo si ejecuta aplicaciones (o cmdlets) que esperan que se configuren.

En un script, usted puede hacer esto:

Push-Location $MyInvocation.MyCommand.Path 
[Environment]::CurrentDirectory = $PWD 
## Your Script Code ... 
Pop-Location 
[Environment]::CurrentDirectory = $PWD 

No hay alternativa a toda prueba de esto. Muchos de nosotros ponemos una línea en nuestra función rápida para establecer [Entorno] :: Directorioactual ... pero eso no lo ayuda cuando está cambiando la ubicación en un script.

Nota final: $PWD no siempre es un CurrentDirectory legal (es posible que el CD en el proveedor de registro por ejemplo), así que si desea poner esto en su prompt, o en las funciones del contenedor para los cmdlets * -Location, necesidad de utilizar:

[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem 
+3

No cambia el directorio de trabajo del proceso debido a los proveedores de rutas: es posible que esté realizando un CD en el registro, una base de datos SQL o una colmena IIS, etc. – piers7

+1

Sí. Lo sé, ese fue el punto de esa última "Nota final". Podrían haberlo (como lo hago en mi función de solicitud) actualizarlo a la ubicación actual del proveedor de FileSystem, como cualquier otro shell del mundo. – Jaykul

+0

Dioses de las escrituras sagradas, ¡estoy TAN DECEPCIONADO '. \ _ /.' - ¡Por esto maté la mitad de mi día! La gente, en serio? ¿En serio? ... – ulidtko

11

menudo he utilizado el siguiente código para importar un módulo que se sientan en el mismo directorio que el script en ejecución. Será primero obtener el directorio desde el que se está ejecutando PowerShell

$ currentPath = Split-Path ((Get-Variable MyInvocation -Ámbito 0) .Value) .MyCommand.Path

import-module " $ currentPath \ sqlps.ps1"

+0

desea establecer el -Escope a la secuencia de comandos –

16

Hay respuestas con gran número de votos, pero cuando leí tu pregunta, pensé que quería saber el directorio donde el guión es, no es que cuando se ejecuta el script.Puede obtener la información con variables auto del powershell

$PSScriptRoot - the directory where the script exists, not the target directory the script is running in 
$PSCommandPath - the full path of the script 

Por ejemplo, tengo $ script de perfil que se encuentra archivo de la solución de Visual Studio y iniciarlo. Quería almacenar la ruta completa, una vez que se inicia un archivo de solución. Pero quería guardar el archivo donde existe el script original. Entonces usé $ PsScriptRoot.

1

Bueno, estaba buscando una solución para esto por un tiempo, sin ningún script solo desde CLI. Así es como lo hago XD:

  • navegar hasta la carpeta de la que desea ejecutar la escritura (Lo importante es que usted tiene la ficha terminaciones)

    ..\..\dir

  • Ahora rodean ubicación con doble comillas, y dentro de ellas agregue cd, para que podamos invocar otra instancia de powershell.

    "cd ..\..\dir"

  • Añadir otro comando para ejecutar secuencias de comandos separados por ;, con es un separador de comandos de PowerShell

    "cd ..\..\dir\; script.ps1"

  • Finalmente ejecutarlo con otra instancia de PowerShell

    start powershell "cd..\..\dir\; script.ps1"

Esto abrirá una nueva ventana de PowerShell, vaya a ..\..\dir, ejecute script.ps1 y cerrar la ventana.


Tenga en cuenta que ";" simplemente separa los comandos, como los tipeó uno por uno, si falla primero se ejecutará el segundo y el siguiente después, y el siguiente después ... Si desea mantener abierta la nueva ventana de powershell, agregue -noexit en el comando pasado. Tenga en cuenta que primero navego a la carpeta deseada para poder usar tabulaciones (no se pueden hacer comillas dobles).

start powershell "-noexit cd..\..\dir\; script.ps1"

Use comillas dobles "" para que pudieran pasar los directorios con espacios de nombres por ejemplo,

start powershell "-noexit cd '..\..\my dir'; script.ps1"

0

Esto funcionaría bien.

Push-Location $PSScriptRoot 

Write-Host CurrentDirectory $CurDir 
Cuestiones relacionadas