제가 디자인하고 있는 데스크탑 환경을 위한 쉘을 만들려고 하는데, 단지 구성된 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
$0
argv[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);
}