in reply to Re: Setting $0 clears /proc/PID/environ too
in thread Setting $0 clears /proc/PID/environ too

I'm really not sure why you're finding it necessary to change the value of $0

Changing the process name is quite common in Unix. If you have access to a Linux system, run this script as root:

#!/usr/bin/perl use v5.12; use warnings; use autodie; use Data::Dumper; for my $dir (sort grep m|^/proc/\d+$|,glob '/proc/*') { say "$dir:"; my $argv0=do { local $/="\0"; open my $f,"$dir/cmdline"; scalar <$f>; }; my $exe=eval { readlink("$dir/exe") }; say Data::Dumper->new([$argv0,$exe],[qw(argv0 exe)])->Dump(); }

On my server, output looks like this (many boring repeated case removed):

/proc/1: $argv0 = 'init [4]'; $exe = '/sbin/init'; /proc/10: $argv0 = undef; $exe = undef; /proc/1001: $argv0 = '/usr/sbin/ypbind'; $exe = '/usr/sbin/ypbind'; /proc/1048: $argv0 = '/usr/sbin/rpc.mountd'; $exe = '/usr/sbin/rpc.mountd'; /proc/105: $argv0 = undef; $exe = undef; /proc/1059: $argv0 = '/usr/sbin/acpid'; $exe = '/usr/sbin/acpid'; /proc/106: $argv0 = undef; $exe = undef; /proc/1069: $argv0 = '/usr/sbin/console-kit-daemon'; $exe = '/usr/sbin/console-kit-daemon'; /proc/107: $argv0 = undef; $exe = undef; /proc/1079: $argv0 = '/usr/sbin/crond'; $exe = '/usr/sbin/crond'; /proc/108: $argv0 = undef; $exe = undef; /proc/1084: $argv0 = '/usr/lib/polkit-1/polkitd'; $exe = '/usr/lib/polkit-1/polkitd'; /proc/13902: $argv0 = '-:0 '; $exe = '/usr/bin/xdm'; /proc/16697: $argv0 = 'sshd: alex [priv]'; $exe = '/usr/sbin/sshd'; /proc/16700: $argv0 = 'sshd: alex@pts/0'; $exe = '/usr/sbin/sshd'; /proc/16701: $argv0 = '-bash'; $exe = '/bin/bash'; /proc/17046: $argv0 = '/usr/bin/perl'; $exe = '/usr/bin/perl5.22.2'; /proc/5156: $argv0 = '/bin/sh'; $exe = '/bin/bash'; /proc/5225: $argv0 = '/opt/exim/bin/exim'; $exe = '/opt/exim/bin/exim-4.72-1'; /proc/5298: $argv0 = '-:1 '; $exe = '/usr/bin/xdm'; /proc/5562: $argv0 = 'postgres: checkpointer process '; $exe = '/opt/pg9/bin/postgres'; /proc/5563: $argv0 = 'postgres: writer process '; $exe = '/opt/pg9/bin/postgres'; /proc/5564: $argv0 = 'postgres: wal writer process '; $exe = '/opt/pg9/bin/postgres'; /proc/5565: $argv0 = 'postgres: autovacuum launcher process '; $exe = '/opt/pg9/bin/postgres'; /proc/5566: $argv0 = 'postgres: stats collector process '; $exe = '/opt/pg9/bin/postgres';

Usually, you will find that argv0 is equal to the absolute path of the executable name. When run manually, it may be just the base name, or the base name of a link to the executable. This happens in the list above for perl5.22.2 invoked as perl, for bash invoked as sh, and for exim-4.72.1 invoked as exim. The init process changes its argv0 to include the runlevel. Postgres fork()s some worker processes, all running from the same executable, and changes their names to indicate their jobs. sshd does something similar to indicate privileged and unprivileged processes and their respective users. xdm changes its name to indicate the X display for which it is responsible. This allows seeing the process state even in a very simple process list.

There are a few processes with neither argv0 nor exe defined, they are created by the Linux kernel for its own purposes.

See also readproctitle from djb's daemontools.


Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^3: Setting $0 clears /proc/PID/environ too
by talexb (Canon) on Jan 17, 2020 at 14:41 UTC

    OK -- changing the process name is fine, and I understand that can be quite handy. I was asking about changing $0, which to me is one of Perl's read-only variables. Then again, Perl's a language (like C) where you can A Weird Thing and the language will shrug and say, OK, Joe! while thinking Hmm, not sure why you'd wanna do that. :) Thanks for the detailed response.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.