ExecStart=@/path/to/executable의 시스템 서비스 접두사는 "argv[0]"을 변경하지 않습니다.

ExecStart=@/path/to/executable의 시스템 서비스 접두사는 "argv[0]"을 변경하지 않습니다.

man systemd.service접두사 사용 설명서 에 따르면 @다음과 같습니다.

실행 파일 경로에 "@" 접두사가 붙은 경우 두 번째로 지정된 토큰은 "argv[0]"(실제 파일 이름 대신)로 실행 프로세스에 전달되고 그 뒤에 지정된 추가 인수가 옵니다.

하지만 bash 스크립트나 python 스크립트를 사용하여 서비스를 실행하면 파일 이름이나 argv[0]이 작동하지 않습니다. 이것은 C 언어로 작성된 프로그램을 사용하는 경우에만 작동합니다.

내 서비스에는 다음이 있습니다.

[Unit]
Description=After service Number: 1

[Service]
Type=oneshot
ExecStart=@/home/edgar/bin/script "after-1-service" "1" "Args from after-service"

[Install]
WantedBy=multi-user.target

다음을 사용하여 이 서비스를 실행할 때프로그램 파일 이름의 값은 다음과 같습니다.“1시 이후 서비스”및 기타 매개변수("1", "애프터 서비스의 매개변수")는 다음과 같이 올바르게 전달됩니다.매개변수[1]그리고매개변수[2]각기.

하지만 내가 사용하여 서비스를 실행할 때파이썬또는세게 때리다스크립트 값“1시 이후 서비스”효과가 없으며 스크립트의 기본 파일 이름을 인쇄합니다. 매개 변수 "1" 및 "Args from after-service"는 다음과 같이 올바르게 전달됩니다.매개변수[1]그리고매개변수[2]각기.

Python 및 bash 스크립트의 경우 어떻게 되나요?“1시 이후 서비스”토론? filename 또는 argv[0]이 무시되면 전달되어야 한다고 생각하기 때문입니다.“1시 이후 서비스”argv[1]과 같이, 다른 인수는 다음과 같아야 합니다.매개변수[2]그리고매개변수[3]

c파일 이름을 인쇄하기 위해 작성한 코드는 다음과 같습니다 .

printf("Filename: %s\n",argv[0]);

이것은 내가 작성한 코드입니다 python.

print(f"Filename:  {sys.argv[0]}")

이것은 내가 작성한 코드입니다 bash.

echo Filename $0  

나는 심볼릭 링크와 파일 이름 변경으로 스크립트를 올바르게 테스트했기 때문에 이것이 C 프로그램에만 적용되거나 systemd(버전 251)의 버그일 수도 있다고 추측합니다.

답변1

여기서 문제는 쉘 프로세스의 프로세스가 쉘 스크립트 내부의 프로세스와 동일하지 않다는 것입니다 argv[0]. $0이는 일반 시작 스크립트에서도 볼 수 있습니다.

$ cat argv0.sh 
#!/bin/sh
echo "Filename $0"
$ sh ./argv0.sh 
Filename ./argv0.sh

쉘은 execve("/bin/sh", ["sh", "./argv0.sh"], [env vars...])ie argv[0]gets set to 과 같은 것을 호출할 것이다 sh. 그러나 스크립트의 이름 $0스크립트실행 후 매뉴얼 페이지는 다음과 같이 말합니다.

0
쉘 또는 쉘 스크립트의 이름으로 확장됩니다. 이는 쉘이 초기화될 때 설정됩니다. bash가 명령 파일을 사용하여 호출되면 $0이는 파일 이름으로 설정됩니다. "

기능에 관한 한 이름이 무엇인지는 중요하지 않습니다.통역사으로 설정되어 있습니다.

나는 이 질문이 원칙적으로 Python과 유사하다고 생각합니다. 예를 들어 매뉴얼에는 다음과 같이 나와 있습니다.

sys.argv
Python 스크립트에 전달된 명령줄 인수 목록입니다. argv[0]스크립트 이름입니다(운영 체제에 따라 전체 경로 이름이거나 아님).

그러나 Python 3.10에는 sys.orig_argv여러분이 찾고 있는 것과 같은 기능도 있습니다.

sys.orig_argv Python 실행 파일에 전달된 명령줄 인수의 원시 목록입니다.


쉘이 시작되면 sh -c "code..." arg0 arg1 ...코드 뒤의 첫 번째 인수가 에 할당되므로 $0이를 사용하고 다음과 같이 코드를 실행할 수 있습니다.

$ sh -c '. ./argv0.sh' foobar
Filename foobar

동일한 내용 등을 . ./argv0.sh볼 수 있도록 동일한 쉘에서 스크립트를 실행하는 데 사용됩니다 .$0

관련 정보