내 스크립트가 로그인 셸로 작동하지 않는 이유는 무엇입니까?

내 스크립트가 로그인 셸로 작동하지 않는 이유는 무엇입니까?

제가 디자인하고 있는 데스크탑 환경을 위한 쉘을 만들려고 하는데, 단지 구성된 Zsh일 뿐인데, 로그인 쉘이라면 어떻게 전달해야 할지 혼란스럽습니다.

이것은 내 스크립트입니다.

#!/bin/sh
case "$0" in
-*) ZDOTDIR=/etc/tiles/zsh exec zsh -l "$@";;
*) ZDOTDIR=/etc/tiles/zsh exec zsh "$@";;
esac

에 설치하고 /bin/tiles-shell해당 경로를 에 추가한 /etc/shells다음 내 쉘로 만들었습니다 chsh.

문제는 $0항상 로그인 쉘이 아닌 것처럼 보인다는 것입니다 /bin/tiles-shell. 언제 시작될 것 같나요? -로그인 셸이어야 하나요?

답변1

이전 값은 Shebang 메커니즘에 의해 지워집니다 argv[0]. 커널은 이를 인터프리터의 경로로 대체합니다.

파일에서 스크립트를 실행할 때 쉘은 argv[0]as의 값을 노출하지 않습니다. 스크립트 파일의 이름입니다. 나는 zsh가 다른 인터페이스를 통해 그것을 노출한다고 생각하지 않습니다.$0$0argv[0]

데모 스크립트(Linux용):

#!/bin/zsh
echo "argv[0]=$(</proc/$$/cmdline tr \\0 \\n | head -n 1)"
echo "\$0=$0"

산출:

% ARGV0=foo zsh -c "$(cat a)"
argv[0]=foo
$0=foo
% ARGV0=foo zsh ./a
argv[0]=foo
$0=./a
% ARGV0=foo ./a
argv[0]=/bin/zsh
$0=./a

로그인 쉘을 스크립트로 사용하려면 로그인 쉘 전용 스크립트로 만드십시오.

답변2

Giles의 답변에 따라 바이너리로 만들었고 작동합니다.

#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    putenv("ZDOTDIR=/etc/tiles/zsh");
    execv("/usr/bin/zsh", argv);
}

관련 정보