![zsh 소스에서 $0을 설정하시겠습니까?](https://rvso.com/image/1586953/zsh%20%EC%86%8C%EC%8A%A4%EC%97%90%EC%84%9C%20%240%EC%9D%84%20%EC%84%A4%EC%A0%95%ED%95%98%EC%8B%9C%EA%B2%A0%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
저는 "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>
command
fifo=<(echo 'hi!'); echo $fifo; cat $fifo
/proc/self/fd/14
hi!
따라서 이것이 트릭을 수행해야 합니다. "사용"이 작동하는지 살펴보겠습니다. 이 스크립트를 $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
하고 해당 컨텍스트에서 이전(로컬)의 유용한 값으로 설정됩니다 . 호출하면 리모콘을 가져와서 해석하려고 시도합니다 . 예:zsh
bin/mycommand
$0
$0
foo-bar-baz
bin/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
무시됨).