With zsh
(since the first release in 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
also has a -
builtin to start a command with -
prepended to argv[0]
(as used to start shells as login shells):
$ - 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 (since 1993), bash (since 2.0 in 1996), zsh (since 4.3.5 in 2008), bosh (since the 2015-08-27 release), mksh (since R52c in 2016), busybox ash
(since 1.27.0 (2017)) at least:
$ (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
With 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
With 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
But beware that when you execute a script (with the execve()
system call) that starts with:
#! /path/to/interpreter optional-arg
as shebang as:
execve("/path/to/script", ["arg0", "arg1", ...], env)
The system transforms it to:
execve("/path/to/interpreter", [something, "optional-arg", "/path/to/script", "arg1", ...], env)
With something
being, depending on the system either /path/to/interpreter
or argv0
(the former on Linux).
And interpreters, when exposing arg lists in their API, expose the argument list of the script, not of the interpreter, so $0
/ sys.argv[0]
will not be something
above, but /path/to/script
.
sys.argv[1]
instead