3

When run with arguments a b c d e f g, this script:

system("ps ww$$");
{
  local $0 = "foo";
  system("ps ww$$");
}
system("ps ww$$");

prints something like:

  PID TTY      STAT   TIME COMMAND
16057 pts/5    S+     0:00 perl /tmp/u a b c d e f g
  PID TTY      STAT   TIME COMMAND
16057 pts/5    S+     0:00 foo
  PID TTY      STAT   TIME COMMAND
16057 pts/5    S+     0:00 /tmp/u

In other words, in the third case ps does not display the original argv array.

Is there a way that the original args (e.g. a b c d e f g) can be restored / displayed via ps?

I'm using Centos and Ubuntu.

ErikR
  • 51,541
  • 9
  • 73
  • 124

2 Answers2

1

place the following at the top of your program:

$0 = "perl $0 @ARGV";
Eric Strom
  • 39,821
  • 2
  • 80
  • 152
0

Interesting. I just tried something similar, showing the value of $0 before invoking ps.

Here's my script:

#!/usr/bin/perl

use strict;
use warnings;

$| = 1;

print "\$0 = $0\n";
system 'ps', "ww$$";
print "\n";

{
    local $0 = 'foo';
    print "\$0 = $0\n";
    system 'ps', "ww$$";
    print "\n";
}

print "\$0 = $0\n";
system 'ps', "ww$$";

and here's the output (the first $ is a shell prompt):

$ ./foo.pl
$0 = ./foo.pl
  PID TTY      STAT   TIME COMMAND
 2478 pts/2    S+     0:00 /usr/bin/perl ./foo.pl

$0 = foo
  PID TTY      STAT   TIME COMMAND
 2478 pts/2    S+     0:00 foo

$0 = ./foo.pl
  PID TTY      STAT   TIME COMMAND
 2478 pts/2    S+     0:00 ./foo.pl

So $0 is restored to its original value, but the information printed by ps is different.

Note that @EricStrom's workaround doesn't quite have the (presumably) intended result; it makes ps show the command name as perl, not /usr/bin/perl (the latter could be useful information).

It appears that Perl is attempting to restore $0 to its original value, but it doesn't quite succeed in restoring the information shown by ps.

I think the bottom line is that modifying $0 can be useful, but the behavior is not 100% reliable or portable.

perldoc perlvar says:

On some (but not all) operating systems assigning to $0 modifies the argument area that the ps program sees. On some platforms you may have to use special ps options or a different ps to see the changes. Modifying the $0 is more useful as a way of indicating the current program state than it is for hiding the program you're running.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I suppose you could use `$0 = "$^X $0 @ARGV"` to capture the exact path of the perl interpreter – ErikR Oct 12 '11 at 20:38
  • @user5402: Yes, but if you invoke it with `perl foo.pl`, then `ps` *doesn't* show the full path to the Perl interpreter. – Keith Thompson Oct 12 '11 at 21:01