programing

PowerShell 스크립트에서 shebang을 사용하려면 어떻게 해야 합니까?

css3 2023. 10. 2. 15:22

PowerShell 스크립트에서 shebang을 사용하려면 어떻게 해야 합니까?

Cygwin에 있는 Bash shell에서 직접 명령어로 호출하고 싶은 PowerShell 스크립트가 몇 개 있습니다.예를 들어 Write-Foo.ps1이라는 파일 이름으로 스크립트를 작성하는 경우 작업 디렉토리의 명령어로 실행합니다.

$ Write-Foo.ps1 arg1 arg2 ...

이를 위해 스크립트를 내 PATH에 추가하고 실행 가능하게 만든 다음 파일 맨 앞에 다음과 같은 인터프리터 shebang/hashbang을 포함합니다.

#!/usr/bin/env powershell

Write-Host 'Foo'
...

이것은 env 유틸리티의 일반적인 사용이지만, 적어도 인터프리터 선언을 위해 Cygwin의 경로 접두사(/cygdrive/c/...)에서 스크립트를 분리합니다.

이것은 PowerShell을 시작할 수 있지만 시스템은 파일을 Cygwin 형식의 경로로 전달합니다. 물론 PowerShell은 이 경로를 이해하지 못합니다.

'/cygdrive/c/path/to/Write-Foo.ps1'이라는 용어는 cmdlet, 함수, 스크립트 파일 또는 작동 가능한 프로그램의 이름으로 인식되지 않습니다.

MSYS(Git Bash)는 스크립트 경로를 올바르게 변환하는 것으로 보이며 파일 경로에 공백이 없는 한 스크립트가 예상대로 실행됩니다.Cygwin의 shebang에 의존하여 PowerShell 스크립트를 직접 호출할 수 있는 방법이 있습니까?

이상적으로는 가능하면 스크립트 이름에서 .ps1 확장자도 생략하고 싶지만 이 제한을 감수해야 할 수도 있음을 알고 있습니다.가능하면 수동으로 앨리어싱하거나 스크립트를 래핑하는 것은 피하고 싶습니다.


이것을 찾는 Linux/macOS 사용자를 위한 간단한 메모.

다음 내용을 찾는 Linux/macOS 사용자를 위한 빠른 참고 사항:

  • pwsh 또는 powershell 명령이 다음에 있는지 확인합니다.PATH
  • 다음 인터프리터 지시사항을 사용:#!/usr/bin/env pwsh
  • 스크립트가 유닉스 스타일 줄 끝을 사용하는지 확인합니다(\n, 아니 \r\n)

Briantist의 의견 덕분에 6.0 이전 버전의 PowerShell에 대해서는 성능 저하 없이 직접 지원되지 않는다는 것을 알게 되었습니다.

...[PowerShell Core 6.0]에서는 위치 매개 변수 0을 다음과 같이 특별히 변경했습니다.‑Command로.‑File당신이 받는 오류 메시지는 그것이 그들에게 길을 주고 있기 때문입니다.‑Command...

Unix와 유사한 시스템은 명령어로 스크립트를 호출할 때 첫 번째 인수로 "shebang"이 지정한 인터프리터에 PowerShell 스크립트의 절대 파일 이름을 전달합니다.일반적으로 PowerShell은 기본적으로 스크립트 파일 이름을 실행 명령으로 해석하기 때문에 PowerShell 5 이하에서도 이 기능이 작동할 수 있습니다.

PowerShell 를 에는 이 할 수 -Command이러한 맥락에서 파일 이름을 프롬프트에서 입력한 것처럼 다시 해석하므로 공백이나 특정 기호가 포함된 스크립트의 경로는 PowerShell이 인수로 보는 "명령어"를 깨게 됩니다.우리는 또한 사전 해석 단계에서 약간의 효율성을 잃습니다.

지정 시-Fileparameter신 PowerShell할 수 .-Command. 안타깝게도, shebang 라인에서 이 옵션을 사용하려면 질문에 설명된 env 유틸리티를 사용하여 얻을 수 있는 이식성을 희생해야 합니다. 운영 체제 프로그램 로더는 보통 인터프리터용 스크립트에서 선언된 프로그램에 대해 하나의 인수만 허용하기 때문입니다.

를 들어 은 두의 인수를 envpowershell그리고.-File):

#!/usr/bin/env powershell -File

반면, MSYS 시스템(Git Bash와 같은)에서는 다음과 같은 지시문(PowerShell에 대한 절대 경로 포함)이 포함된 PowerShell 스크립트가 예상대로 실행됩니다.

#!/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -File

...그러나 동일한 파일 시스템 규약을 따르지 않는 다른 시스템에서는 스크립트를 직접 실행할 수 없습니다.


이것 또한 Cygwin의 원래 문제를 해결하지 못합니다.이 질문에서 설명한 대로 스크립트 경로 자체는 Windows 스타일 경로로 변환되지 않으므로 PowerShell에서 (버전 6에서도) 파일을 찾을 수 없습니다.몇 가지 해결책을 찾아냈지만, 완벽한 해결책을 제시하지는 못했습니다.

가장 은 PowerShell 의입니다의 입니다.-Command매개 변수. 추가 후 추가 에.Write-Foo.ps1 스크립트 (트()PATH할 수 extension 하여 PowerShell , .

$ powershell Write-Foo arg1 arg2 ...

스크립트 파일 자체에 파일 이름에 공백이 없는 한, 이를 통해 작업 디렉토리에서 스크립트를 실행할 수 있습니다.하여 PowerShell합니다.PATH가 없습니다 .명령 이름에 대한 Bash의 탭 완료를 잃게 됩니다.

Cygwin에서 shebang을 작동시키려면 호출된 스크립트의 경로 스타일을 PowerShell이 이해할 수 있는 형식으로 변환하는 프록시 스크립트를 작성해야 했습니다.pwsh(PS 6로 휴대성을 위해)라고 불렀고 그 안에 놓았습니다.PATH:

#!/bin/sh

if [ ! -f "$1" ]; then 
    exec "$(command -v pwsh.exe || command -v powershell.exe)" "$@"
    exit $?
fi

script="$(cygpath -w "$1")"
shift

if command -v pwsh.exe > /dev/null; then 
    exec pwsh.exe "$script" "$@"
else
    exec powershell.exe -File "$script" "$@"
fi

스크립트는 첫 번째 인수를 확인하는 것으로 시작합니다.파일이 아니면 파워쉘을 정상적으로 시작합니다.그렇지 않으면 스크립트가 파일 이름을 Windows 스타일 경로로 변환합니다.버전 6의 pwsh.exe를 사용할 수 없는 경우 이 예제는 powershell.exe로 돌아갑니다.그러면 스크립트에서 다음과 같은 인터프리터 지시를 사용할 수 있습니다.

#!/usr/bin/env pwsh

...직접 스크립트를 호출합니다.

$ Write-Foo.ps1 arg1 arg2 ...

6.0 이전 버전의 PowerShell에서는 확장자 없이 원본을 생성하려면 스크립트를 symlink로 확장하거나 .ps1 확장자로 임시 PowerShell 스크립트를 작성할 수 있습니다.

언급URL : https://stackoverflow.com/questions/48216173/how-can-i-use-a-shebang-in-a-powershell-script