Ign*_*ams 27
您可以在运行新程序时执行此操作exec -a <newname>.
Vin*_*ond 10
只是为了记录,即使它没有完全回答原始海报的问题,这是一件微不足道的事情zsh:
ARGV0=emacs nethack
Run Code Online (Sandbox Code Playgroud)
我假设您有一个您希望执行的shell脚本,以便脚本进程本身有一个新的argv[0].例如(我只在bash中测试过这个,所以我正在使用它,但这可能在其他地方有用).
#!/bin/bash
echo "process $$ here, first arg was $1"
ps -p $$
Run Code Online (Sandbox Code Playgroud)
输出将是这样的:
$ ./script arg1
process 70637 here, first arg was arg1
PID TTY TIME CMD
70637 ttys003 0:00.00 /bin/bash ./script arg1
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下ps显示shell /bin/bash.现在尝试你的交互式shell exec -a,但是在子shell中你不要吹掉交互式shell:
$ (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
Run Code Online (Sandbox Code Playgroud)
Woops,仍然显示/bin/bash.发生了什么?在exec -a大概也设定argv[0],但随后的bash的新实例启动,因为操作系统读取#!/bin/bash你的脚本的顶部.好的,如果我们以某种方式在脚本中执行exec'ing会怎么样?首先,我们需要一些方法来检测这是脚本的第一次执行,还是第二次exec编辑实例,否则第二个实例将再次执行,并在无限循环中依次执行.接下来,我们需要可执行文件不是#!/bin/bash顶部有一行的文件,以防止操作系统更改我们想要的argv [0].这是我的尝试:
$ cat ./script
#!/bin/bash
__second_instance="__second_instance_$$"
[[ -z ${!__second_instance} ]] && {
declare -x "__second_instance_$$=true"
exec -a MyScript "$SHELL" "$0" "$@"
}
echo "process $$ here, first arg was $1"
ps -p $$
Run Code Online (Sandbox Code Playgroud)
由于这个答案,我首先测试环境变量__second_instance_$$,基于PID(不会改变exec),以便它不会与使用这种技术的其他脚本冲突.如果它是空的,我认为这是第一个实例,我导出该环境变量,然后是exec.但是,重要的是,我不执行此脚本,但我直接执行shell二进制文件,将此script($0)作为参数,并传递所有其他参数($@).环境变量有点像黑客.
现在输出是这样的:
$ ./script arg1
process 71143 here, first arg was arg1
PID TTY TIME CMD
71143 ttys008 0:00.01 MyScript ./script arg1
Run Code Online (Sandbox Code Playgroud)
那几乎就在那里.该argv[0]是MyScript像我想要的,但有额外的ARG ./script在那里是直接执行壳(而不是通过操作系统的的结果#!处理).不幸的是,我不知道如何比这更好.
Bash 5.0的更新
看起来Bash 5.0增加了对写入特殊变量BASH_ARGV0的支持,所以这应该变得更加简单.
(见发布公告)
小智 5
( exec -a foo bash -c 'echo $0' )
Run Code Online (Sandbox Code Playgroud)