如何在bash中更改argv0所以命令在ps中显示不同的名称?

bst*_*rre 23 bash ps argv

在C程序中,我可以编写argv [0],新名称显示在ps列表中.

我怎么能用bash做到这一点?

Ign*_*ams 27

您可以在运行新程序时执行此操作exec -a <newname>.

  • 不幸的是,它不会影响*current*shell.你必须使用它打开一个新的. (4认同)
  • 在Bash 4.0.33中似乎对我没有任何影响 (2认同)

Vin*_*ond 10

只是为了记录,即使它没有完全回答原始海报的问题,这是一件微不足道的事情zsh:

ARGV0=emacs nethack
Run Code Online (Sandbox Code Playgroud)


bst*_*rre 9

我有机会通过bash的源代码,看起来没有任何支持写入argv [0].


Pat*_*ick 7

我假设您有一个您希望执行的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)

  • 好吧,它分叉了一个子 shell,然后用“exec”启动的进程替换该子 shell。这与您简单地输入“bash -c 'echo $0”时发生的情况几乎相同 (2认同)