[powershell] PowerShell : 스크립트 디렉토리에서 명령 실행

스크립트의 현재 디렉토리를 사용하여 몇 가지 작업을 수행하는 PowerShell 스크립트가 있습니다. 따라서 해당 디렉토리 내부에서 실행 .\script.ps1이 올바르게 작동합니다.

이제 스크립트의 참조 디렉토리를 변경하지 않고 다른 디렉토리에서 해당 스크립트를 호출하려고합니다. 그래서 전화를 걸고 ..\..\dir\script.ps1그 스크립트가 디렉토리 내부에서 호출 된 것처럼 동작하기를 원합니다.

이를 수행하는 방법 또는 스크립트를 수정하여 모든 디렉토리에서 실행할 수 있습니까?



답변

스크립트 옆에 파일을 참조 할 수 있도록 스크립트 자체 경로를 원하십니까? 이 시도:

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

$ MyInvocation 및 해당 속성에서 많은 정보를 얻을 수 있습니다.

현재 작업 디렉토리에서 파일을 참조하려면 Resolve-Path 또는 Get-ChildItem을 사용할 수 있습니다.

$filepath = Resolve-Path "somefile.txt"

편집 (OP의 의견을 기반으로 함) :

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

# do stuff, call ant, etc

# now back to previous directory
Pop-Location

Invoke-Command를 사용하여 비슷한 것을 달성하는 다른 방법이있을 수 있습니다.


답변

기본 앱을 호출하는 경우 [Environment]::CurrentDirectoryPowerShell의 $PWD현재 디렉토리에 대해 걱정 하지 않아도됩니다 . 여러 가지 이유로, PowerShell은 Set-Location 또는 Push-Location을 수행 할 때 프로세스의 현재 작업 디렉터리를 설정하지 않으므로 설정 될 것으로 예상되는 응용 프로그램 (또는 cmdlet)을 실행중인 경우 그렇게해야합니다.

스크립트에서 다음을 수행 할 수 있습니다.

$CWD = [Environment]::CurrentDirectory

Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
##  Your script code calling a native executable
Pop-Location

# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD

이것에 대한 완벽한 대안은 없습니다. 우리의 대부분은 세트에 우리의 프롬프트 기능에서 [환경] ::은 CurrentDirectory을 라인을 넣어 …하지만 당신이 위치를 변경하는 때 당신을 도움이되지 않습니다 내에서 스크립트를.

이것이 PowerShell에 의해 자동으로 설정되지 않는 이유에 대한 두 가지 참고 사항 :

  1. PowerShell은 다중 스레드 일 수 있습니다. 단일 프로세스 내에서 여러 Runspace (RunspacePool 및 PSThreadJob 모듈 참조)를 동시에 실행할 수 있습니다. 각 실행 영역에는 고유 한 $PWD현재 작업 디렉토리가 있지만 하나의 프로세스와 하나의 환경 만 있습니다.
  2. 단일 스레드 인 $PWD경우에도 항상 유효한 CurrentDirectory가 아닙니다 (예 : 레지스트리 공급자에 CD를 넣을 수 있음).

프롬프트에 넣으려면 (단일 스레드의 주 실행 영역에서만 실행) 다음을 사용해야합니다.

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


답변

투표 수가 많은 답변이 있지만 질문을 읽을 때 스크립트가 실행되는 디렉토리가 아니라 스크립트가있는 디렉토리를 알고 싶다고 생각했습니다. powershell의 자동 변수를 사용하여 정보를 얻을 수 있습니다

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

예를 들어 Visual Studio 솔루션 파일을 찾아 시작하는 $ profile 스크립트가 있습니다. 솔루션 파일이 시작되면 전체 경로를 저장하고 싶었습니다. 그러나 원본 스크립트가 존재하는 곳에 파일을 저장하고 싶었습니다. 그래서 $ PsScriptRoot를 사용했습니다.


답변

필자는 종종 다음 코드를 사용하여 실행중인 스크립트와 동일한 디렉토리에있는 모듈을 가져 왔습니다. 먼저 powershell이 ​​실행되는 디렉토리를 가져옵니다.

$ currentPath = 분할 경로 ((Get-Variable MyInvocation -Scope 0) .Value) .MyCommand.Path

가져 오기 모듈 “$ currentPath \ sqlps.ps1”


답변

이것은 잘 작동합니다.

Push-Location $PSScriptRoot

Write-Host CurrentDirectory $CurDir


답변

CLI에서 스크립트를 사용하지 않고 잠시 동안이 솔루션을 찾고있었습니다. 이것이 내가 xD를 수행하는 방법입니다.

  • 스크립트를 실행할 폴더로 이동하십시오 (중요한 것은 탭 완성이 있다는 것입니다)

    ..\..\dir

  • 이제 큰 따옴표로 위치를 둘러싸고 그 안에 add을 추가 cd하여 다른 powershell 인스턴스를 호출 할 수 있습니다.

    "cd ..\..\dir"

  • ;powershell의 명령 구분 기호를 사용하여으로 구분 된 스크립트를 실행하려면 다른 명령을 추가하십시오.

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

  • 마지막으로 powershell의 다른 인스턴스로 실행하십시오.

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

그러면 새로운 powershell 창이 열리고으로 이동하여 창을 닫고 ..\..\dir실행 script.ps1합니다.


“;” 명령을 하나씩 입력 한 것처럼 첫 번째로 실패하면 두 번째로 실행되고 다음에 다음에 다음에 다음 명령이 분리됩니다. 먼저 원하는 폴더로 이동하여 탭 완성을 사용할 수 있습니다 (큰 따옴표는 사용할 수 없음).

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

큰 따옴표를 사용 ""하여 이름에 공백이있는 디렉토리를 전달할 수 있습니다.

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


답변

@JohnL의 솔루션에서 하나의 라이너를 만들었습니다.

$MyInvocation.MyCommand.Path | Split-Path | Push-Location