나는 수년(수십년) 전에 다음과 같이 말할 수 있는 시스템을 사용했던 것을 기억합니다.
$ 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)부터 이 명령이 있음 을 알 수 있습니다.