如何在bash中更改argv0,使命令在ps中以不同的名称显示?
在C程序中,我可以编写argv[0],新名称将显示在ps列表中如何在bash中更改argv0,使命令在ps中以不同的名称显示?,bash,argv,ps,Bash,Argv,Ps,在C程序中,我可以编写argv[0],新名称将显示在ps列表中 如何在bash中实现这一点?您可以在通过exec-a运行新程序时实现这一点,我只想补充一点,至少在某些环境中,这必须在运行时实现。在linux上用perl分配$0确实会改变ps中显示的内容。但是,我不知道这是如何实现的。如果我能找到,我会更新这个 编辑: 基于perl的工作方式,它是非常重要的。我怀疑在运行时是否有任何内置的bask方法,但不确定。您可以看到。我有机会浏览了bash的源代码,但它似乎不支持写入argv[0]。我假设您
如何在bash中实现这一点?您可以在通过
exec-a
运行新程序时实现这一点,我只想补充一点,至少在某些环境中,这必须在运行时实现。在linux上用perl分配$0确实会改变ps中显示的内容。但是,我不知道这是如何实现的。如果我能找到,我会更新这个
编辑:
基于perl的工作方式,它是非常重要的。我怀疑在运行时是否有任何内置的bask方法,但不确定。您可以看到。我有机会浏览了bash的源代码,但它似乎不支持写入argv[0]。我假设您有一个希望执行的shell脚本,以便脚本进程本身有一个新的
argv[0]
。例如(我只在bash中测试过这个,所以我正在使用它,但它可能在其他地方工作)
输出如下所示:
$ ./script arg1
process 70637 here, first arg was arg1
PID TTY TIME CMD
70637 ttys003 0:00.00 /bin/bash ./script arg1
因此,在本例中,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
Woops,仍然显示/bin/bash
。发生了什么事?exec-a
可能确实设置了argv[0]
,但随后启动了一个新的bash实例,因为操作系统读取了#/bin/bash
位于脚本顶部。好吧,如果我们以某种方式在脚本内部执行该怎么办?首先,我们需要某种方法来检测这是脚本的“第一次”执行还是第二次执行,exec
ed实例,否则第二个实例将再次执行,并在无限循环中继续执行。接下来,我们需要可执行文件不是带有#的文件/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 $$
由于,我首先基于PID(不会通过exec
更改)测试环境变量\uu第二个实例$$
,以便它不会与使用此技术的其他脚本冲突。如果它是空的,我假设这是第一个实例,我导出环境变量,然后执行。但是,重要的是,我不执行此脚本,而是直接执行shell二进制文件,使用此脚本($0
)作为参数,同时传递所有其他参数($@
)。环境变量有点像黑客
现在输出如下:
$ ./script arg1
process 71143 here, first arg was arg1
PID TTY TIME CMD
71143 ttys008 0:00.01 MyScript ./script arg1
差不多了。argv[0]
是我想要的MyScript
,但是其中有额外的arg/script
,这是直接执行shell的结果(而不是通过操作系统的!
处理)。不幸的是,我不知道怎样才能比这更好
Bash 5.0的更新
看起来Bash5.0增加了对写入特殊变量的支持,所以这应该会变得简单得多
(请参阅)请记录在案,尽管它没有准确回答原始海报的问题,但这与
zsh
无关:
ARGV0=emacs nethack
将bash可执行文件复制到其他名称 您可以在脚本本身中执行此操作
cp /bin/bash ./new-name
PATH=$PATH:.
exec new-name $0
如果您试图假装自己不是一个shell脚本,您可以将脚本本身重命名为酷的名称,甚至可以将其重命名为“”(一个空格)
将执行bash脚本,并在ps列表中显示为新名称
好的,所以调用脚本“”是一个非常糟糕的主意:)
基本上,改变名字
bash script
重命名bash并重命名脚本
如果你担心的话,就像麦克道姆先生。显然,关于将二进制文件复制到一个新名称(这是完全安全的),您还可以创建一个符号链接
ln -s /bin/bash ./MyFunkyName
./MyFunkyName
这样,符号链接就出现在ps列表中。(再次使用PATH=$PATH:。如果您不需要./)您的意思是要运行一个bash shell脚本,并让它的名称在ps中显示为“bash”以外的其他名称吗?如果我编写一个名为
foo.sh
的脚本,它在ps中显示为foo.sh。我想让它显示为bar.sh
。顺便说一句,我怀疑写argv0是否合法,特别是如果你写的东西比原来的长,但我需要找到一个参考。使用zsh
:+1:很容易,而且要添加到上面,你可以有一个“如果$0不是我想要的,那么‘exec-a what_I__想要的’”在顶部…在Bash 4.0.33中似乎对我没有任何影响。不幸的是,它不影响当前的shell。您必须使用它打开一个新的。这将重新启动进程。与写入argv[0]更改名称不同。它派生一个子shell,然后用exec
启动的进程替换该子shell。这与您只需键入bash-c'echo$0'
时发生的情况几乎相同,我希望没有新手看到真正重命名bash和重命名脚本。我相信这会破坏很多东西!:)它确实是以“将bash可执行文件复制到另一个名称”开始的,而且命令很清楚。我经常这样做,如果我想要一个具有不同名称的bin,不破坏任何东西来更改二进制文件的名称,显然您需要将/bin/bash保留在原来的位置。有时,根据所使用的名称,垃圾箱的行为有所不同,但它们通常也有默认行为。自从我破解bash代码并编译自己的版本以来,我就经常使用bash。您好,Teknopaul,是的(我读过并理解),但您知道如何复制和粘贴champs操作-也许可以编辑答案来说明为什么要将bash复制到另一个名称;)如果有人改变了真相。。。如果他们重新启动并且没有提示,他们将处于危险状态。如果他们复制粘贴,它是完全安全的cp/bin/bash/任何不会造成任何损害的东西。答案确实说明了原因。如果您想更改ps列表中显示的内容,一个明显的方法是更改正在调用的二进制文件的名称。执行官会让你
exec new-name " "
bash script
ln -s /bin/bash ./MyFunkyName
./MyFunkyName