명령줄에서 argv[0] 변경

명령줄에서 argv[0] 변경

나는 수년(수십년) 전에 다음과 같이 말할 수 있는 시스템을 사용했던 것을 기억합니다.

$ realname:newname A B C

그리고 프로그램은 이라고 불릴 것입니다 argv = { "newname", "A", "B", "C" }.

그런데 그게 무슨 껍질이었는지는 기억이 나지 않습니다.

이 기능이 현재 쉘에 존재합니까?

고쳐 쓰다:

exec -a이것이 내가 원하는 것처럼 보이지만 프로그램의 언어에 따라 일관되지 않은 동작이 발생합니다(예, 잘못된 코드라는 것을 알고 있습니다).

$ cat argv.c  && cc argv.c
int main(int argc, char **argv) { printf("<< %s >>\n", argv[0]); }

$ (exec -a fake ./a.out)
<< fake >>

"C"에서는 잘 작동하지만 Python에서는 작동하지 않습니다.

$ cat argv.py
#!/usr/bin/python3
import sys
print("<<", sys.argv[0], ">>")

$ (exec -a fake ./argv.py)
<< /home/ray/test/argv.py >>

답변1

zsh(1990년 처음 출판된 이후):

$ ARGV0="new value for ps's argv[0]" ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
stephane   45193    2195  0 12:08 pts/11   00:00:00 /bin/zsh
stephane   45510   45193  0 12:15 pts/11   00:00:00 new value for ps's argv[0] -f

zsh사전 -명령을 시작하는 내장 명령 도 있습니다 (로그인 쉘로 쉘을 시작하는 데 사용됨).-argv[0]

$ - ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
stephane    2221    2195  0 06:21 pts/4    00:00:01 /bin/zsh
stephane   46537    2221  0 12:42 pts/4    00:00:00 -ps -f

ksh(1993년부터), bash(1996년 2.0부터),다루기 힘든(2008 4.3.5 이후), bosh (2015-08-27 이후), mksh (2016 R52c 이후), busybox ash(1.27.0 (2017) 이후) 적어도:

$ (exec -a "new value for ps's argv[0]" ps -f)
UID          PID    PPID  C STIME TTY          TIME CMD
stephane    2221    2195  0 06:21 pts/4    00:00:01 /bin/zsh
stephane   46558    2221  0 12:43 pts/4    00:00:00 new value for ps's argv[0] -f

그리고 perl:

$ perl -e 'exec {shift} @ARGV' /bin/ps "new value for ps's argv[0]" -f
UID          PID    PPID  C STIME TTY          TIME CMD
stephane   46585    2195  0 12:44 pts/14   00:00:00 /bin/zsh
stephane   46646   46585  0 12:45 pts/14   00:00:00 new value for ps's argv[0] -f

그리고 python:

$ python3 -c 'import os; import sys; os.execvp(sys.argv[1], sys.argv[2:])' ps "new value for ps's argv[0]" -f 
UID          PID    PPID  C STIME TTY          TIME CMD
stephane   46585    2195  0 12:44 pts/14   00:00:00 /bin/zsh
stephane   46985   46585  0 12:53 pts/14   00:00:00 new value for ps's argv[0] -f

execve()그러나 시스템 호출을 사용하여 다음으로 시작하는 스크립트를 실행할 때 주의하세요.

#! /path/to/interpreter optional-arg

셰르본으로서:

execve("/path/to/script", ["arg0", "arg1", ...], env)

시스템은 이를 다음으로 변환합니다.

execve("/path/to/interpreter", [something, "optional-arg", "/path/to/script", "arg1", ...], env)

존재 와 함께 something,시스템에 따라 다름또는 (Linux에서는 전자 /path/to/interpreter) argv0.

인터프리터가 API에 인수 목록을 노출하면 매개변수 목록도 노출됩니다.스크립트된, 아니요통역사이므로 $0/가 맨 위에 sys.argv[0]표시되지는 않지만 .something/path/to/script

답변2

인라인 스크립트를 실행하는 옵션을 사용하여 셸을 시작할 때 -c첫 번째 인수는 다음 위치에 배치됩니다 $0.

$ sh -c 'printf "0: %s\n" "$0"; printf "Other: %s\n" "$@"'  hello there how are you
0: hello
Other: there
Other: how
Other: are
Other: you

에서 bash에 할당하면 현재 셸의 값이 BASH_ARGV0변경됩니다 .$0

$ printf '%s\n' "$0"
/usr/local/bin/bash
$ BASH_ARGV0="hello"
$ printf '%s\n' "$0"
hello

(그러나 내 시스템의 프로세스 이름은 변경되지 않습니다)

다음을 사용하여 다른 매개변수를 변경할 수 있습니다 set.

$ printf '%s\n' "$@"

$ set -- A B C
$ printf '%s\n' "$@"
A
B
C

답변3

대부분의 시스템에서는 심볼릭 링크로 충분할 것입니다:

~$ cat test.c 
#include <stdio.h>

int main(int ac, char **av)
{
    printf("%s\n", av[0]);
}
~$ cc -o test test.c
~$ ./test 
./test
~$ ln -s test coincoin 
~$ ./coincoin 
./coincoin

busybox이는 하나의 바이너리만 사용하여 여러 유틸리티(핑, 라우팅 등)를 구현하는 메커니즘(임베디드 시스템에서 널리 사용됨)입니다 .

답변4

완전성을 기하기 위해 FreeBSD 포트에는 argv0버전 7.1(2009)부터 이 명령이 있음 을 알 수 있습니다.

관련 정보