我记得很多年(几十年)前使用过一个系统,人们可以这样说:
$ realname:newname A B C
并且该程序将被调用argv = { "newname", "A", "B", "C" }
。
不过我不记得这是什么壳了。
当前的 shell 中是否存在这种功能?
更新:
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]
(用于将 shell 作为登录 shell 启动):
$ - 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 中公开 arg 列表时,会公开参数列表脚本的, 不是口译员的,所以$0
/sys.argv[0]
不会在something
上面,但是/path/to/script
.
答案2
当使用其选项启动 shell-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
,分配 toBASH_ARGV0
会更改当前 shell 的$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
(广泛用于嵌入式系统)仅使用一个二进制文件来实现多个实用程序(ping、路由等)。
答案4
为了完整起见,我看到 FreeBSD portsargv0
从版本 7.1 (2009) 开始就有这个命令