zsh 소스에서 $0을 설정하시겠습니까?

zsh 소스에서 $0을 설정하시겠습니까?

저는 "ssh를 통한 심볼릭 링크"처럼 동작하는 명령을 생성하려고 합니다. 즉, 마치 로컬에서 호출된 것처럼 원격 스크립트를 호출합니다. 내 스크립트는 다음과 같습니다

#!/bin/zsh
if (( "$#" = 0 )); then
    echo "Usage: $0 <number>" >&2; exit 1
fi
if ! [[ "$1" =~ '^[0-9]+$' ]]; then
    echo "error: “$1” is not a valid number" >&2; exit 1
fi

이를 위해 와 같은 경로로 fifo를 생성하고 의 stdout을 해당 경로로 리디렉션 하고 해당 경로를 평가하는 <(command)프로세스 대체를 사용하겠습니다 . 에코 (또는 그렇게) 한 다음 ./proc/self/fd/<n>commandfifo=<(echo 'hi!'); echo $fifo; cat $fifo/proc/self/fd/14hi!

따라서 이것이 트릭을 수행해야 합니다. "사용"이 작동하는지 살펴보겠습니다. 이 스크립트를 $PATH에 저장하고 파일 이름으로 실행하겠습니다 exec-remote.

#!/bin/zsh
source <(ssh myserver 'cat bin/mycommand')

거의! 결과적으로 원격 스크립트는 다음과 같이 말합니다.

Usage: /proc/self/fd/12 <number>

대신에

Usage: exec-remote <number>

… 이는 원격 스크립트의 코드를 소싱하는 동안 $0프로세스 대체의 FIFO 경로로 설정됨을 의미합니다.

그러나 zsh의 source명령은 위치 매개변수( )만 허용하는 것 같습니다 $@.

#!/bin/zsh
source <(ssh myserver 'cat bin/mycommand') $0

… 내 스크립트는 다음과 같이 말하게 될 것입니다:

error: “/proc/self/fd/12” is not a valid number

$0그렇다면 zsh가 그렇게 할 때 혼자 남겨두고 원격 코드를 실행하도록 하려면 어떻게 해야 합니까 ?

답변1

내 생각 source엔 방해가 될 뿐인 것 같아. 다음을 (로컬로) 다음과 같이 저장합니다 exec-from-myserver.

#!/bin/sh
name=${0##/}
exec zsh -c "$(ssh myserver "cat 'bin/$name'")" "$0" "$@"

실행 가능하게 만든 다음 심볼릭 링크로 연결합니다.

ln -s exec-from-myserver mycommand
ln -s exec-from-myserver foo-bar-baz
# etc.

(참고: 문자열 cat 'bin/whatever_name_you_chose'파싱된먼쪽에. 리터럴이 포함된 이름은 '코드를 손상시키거나 오작동하게 만듭니다. 특정 방식으로 심볼릭 링크의 이름을 지정하여 코드 삽입을 수행할 수도 있습니다. 이름을 선택하는 사람은 바로 당신이므로 그다지 중요하지 않습니다. 일반적인 이름을 사용하면 괜찮습니다.)

이제 을 호출하면 mycommand로컬 스크립트는 원격을 해석 exec하고 해당 컨텍스트에서 이전(로컬)의 유용한 값으로 설정됩니다 . 호출하면 리모콘을 가져와서 해석하려고 시도합니다 . 예:zshbin/mycommand$0$0foo-bar-bazbin/foo-bar-baz

$ ./mycommand
Usage: ./mycommand <number>
$ # This was your remote script talking.

$ ./mycommand 1
$ # Executed without complaint.

$ ././mycommand
Usage: ././mycommand <number>
$ # As you can see the remote script is aware of its local name and path used.

$ ./foo-bar-baz 
cat: bin/foo-bar-baz: No such file or directory
$ # This was the remote cat talking, only because there is no remote foo-bar-baz.

노트:

  • 내 용어의 미묘한 차이는 다음과 같습니다. "원격 스크립트"는 원격 측에 파일로 존재하지만 로컬로 해석됩니다. "외딴 고양이"는 정말 멀리 떨어져 있습니다.
  • exec-from-myserver항상 사용하면 zsh -c원격 스크립트의 shebang이 완전히 무시됩니다(실험에서도 source무시됨).

관련 정보