확인 bash에서 argv0를 바꾸는 방법은 명령어가 ps에 다른 이름으로 나타나므로?




리눅스 백그라운드 프로세스 확인 (6)

bash 실행 파일을 다른 이름으로 복사하십시오.

스크립트 자체에서이 작업을 수행 할 수 있습니다 ...

cp /bin/bash ./new-name
PATH=$PATH:.
exec new-name $0

쉘 스크립트가 아니라면 스크립트 자체를 멋진 곳이나 심지어는 ""한 칸으로 바꿀 수 있습니다.

exec new-name " "

스크립트를 bash로 실행하고 ps 목록에 new-name 으로 나타납니다.

""스크립트를 호출하는 것은 매우 나쁜 생각입니다. :)

기본적으로 이름을 변경하려면

bash script

bash의 이름을 바꾸고 스크립트의 이름을 바꿉니다.

당신이 걱정된다면, Mr McDoom. 분명히 바이너리를 새로운 이름으로 복사하는 것 (완전히 안전하다)은 심볼릭 링크를 만들 수도있다.

ln -s /bin/bash ./MyFunkyName
./MyFunkyName

이 방법으로 심볼릭 링크는 ps 목록에 나타납니다. (다시 PATH = $ PATH :를 사용하십시오.

C 프로그램에서 나는 argv [0]을 쓸 수 있고 새 이름이 ps 목록에 나타납니다.

어떻게하면 bash에서이 작업을 수행 할 수 있습니까?


( exec -a foo bash -c 'echo $0' ) 

적어도 일부 환경에서는 런타임에 가능해야한다고 덧붙일 것입니다. 리눅스에서 Perl로 $ 0을 지정하면 ps에 나타나는 내용이 바뀝니다. 그러나 어떻게 구현되는지 모르겠습니다. 내가 알아낼 수 있으면, 나는 이것을 업데이트 할 것이다.

편집 : Perl이 그것을 어떻게하는지에 따라, 그것은 사소하지 않습니다. 나는 거기에 런타임에 방법에 내장 된 모든 통근하지만 의심의 여지가 확실하지 않습니다. perl이 런타임시 프로세스 이름을 설정하는 방법 을 볼 수 있습니다.


스크립트 프로세스 자체에 새로운 argv[0] 가 있도록 실행하고 싶은 쉘 스크립트가 있다고 가정합니다. 예를 들어 (나는 이것을 bash에서 테스트 했으므로 이것을 사용하고 있지만 다른 곳에서도 작동 할 수 있습니다).

#!/bin/bash

echo "process $$ here, first arg was $1"
ps -p $$

출력은 다음과 같습니다.

$ ./script arg1
process 70637 here, first arg was arg1
  PID TTY           TIME CMD
70637 ttys003    0:00.00 /bin/bash ./script arg1

따라서 ps 는이 경우 /bin/bash 쉘을 보여줍니다. 이제 대화 형 셸의 exec -a 시도해보십시오. 그러나 하위 쉘에서는 대화 형 셸을 날려 버리지 마십시오.

$ (exec -a MyScript ./script arg1)
process 70936 here, first arg was arg1
  PID TTY           TIME CMD
70936 ttys008    0:00.00 /bin/bash /path/to/script arg1

Woops, 여전히 /bin/bash 보여줍니다. 어떻게 된 거예요? exec -a 아마도 argv[0] 설정했지만 운영 체제가 스크립트의 맨 위에 #!/bin/bash 를 읽기 때문에 bash의 새로운 인스턴스가 시작되었습니다. 우리가 어떻게 든 스크립트 내에서 exec'ing을 수행하면 어떨까요? 먼저 스크립트의 첫 번째 실행인지 아니면 두 번째 exec 인스턴스인지를 감지하는 방법이 필요합니다. 그렇지 않으면 두 번째 인스턴스가 다시 exec되고 무한 루프가 반복됩니다. 다음으로, OS가 원하는 argv [0]을 변경하지 못하도록 맨 위에 #!/bin/bash 행이있는 파일이 아니 도록 실행 파일이 필요합니다. 내 시도는 다음과 같습니다.

$ cat ./script
#!/bin/bash

__second_instance="__second_instance_$$"
[[ -z ${!__second_instance} ]] && {
  declare -x "__second_instance_$$=true"
  exec -a MyScript "$SHELL" "$0" "[email protected]"
}

echo "process $$ here, first arg was $1"
ps -p $$

이 대답 덕분에이 기술을 사용하는 다른 스크립트와 충돌하지 않도록 PID ( exec 통해 변경되지 않음)를 기반으로 환경 변수 __second_instance_$$ 를 먼저 테스트합니다. 비어있는 경우 이것이 첫 번째 인스턴스라고 가정하고 해당 환경 변수를 내 보낸 다음 exec로 보냅니다. 하지만 중요한 것은이 스크립트를 실행하지 않지만이 스크립트 ( $0 )를 인수로 사용하여 다른 모든 인수 ( [email protected] )도 함께 전달하는 쉘 바이너리를 직접 실행합니다. 환경 변수는 약간의 해킹입니다.

이제 결과는 다음과 같습니다.

$ ./script arg1
process 71143 here, first arg was arg1
  PID TTY           TIME CMD
71143 ttys008    0:00.01 MyScript ./script arg1

거의 다 왔어. argv[0]MyScript .하지만 쉘에 직접 실행하는 결과 인 arg / ./script 가 있습니다 (OS의 #! 처리 대신). 불행히도, 나는 이것보다 더 잘하는 법을 모른다.


exec -a <newname> 통해 새 프로그램을 실행할 때이 작업을 수행 할 수 있습니다.


단지 기록을 위해 원래의 포스터의 질문에 정확하게 대답하지는 않지만 zsh 와는 관계없는 것이 있습니다.

ARGV0=emacs nethack




ps