HalNineThousand has asked for the wisdom of the Perl Monks concerning the following question:

I know I can use various tricks so a Perl script can find its own location and that I can use @ARGV to get command line arguments. What I can't find is a way for a script to get the entire command line used to run it, including IO redirection and so on.

Is there a way to get the full command line used to run a Perl script?

Thanks!

Replies are listed 'Best First'.
Re: Get Entire Command Line of a Program
by Corion (Patriarch) on Oct 14, 2010 at 20:17 UTC

    Perl never sees the redirection. The redirection is handled by the shell invoking your program.

    If you just want to launch another program as if it were your program, see exec.

    Otherwise, maybe you can tell us what you want to achieve, then we can maybe give you a better way of getting there.

Re: Get Entire Command Line of a Program
by ikegami (Patriarch) on Oct 14, 2010 at 21:17 UTC

    The shell does not pass the command you gave it to the applications it launches as a result. (Not at all in unix, and only partially in Windows.)

    • Note that one command can launch multiple applications.
    • Note that there might not even be a shell involved, in which case there wouldn't even be a shell command.
    • Note that all shells don't use the same syntax for their commands.

    Clearly, you're barking up the wrong tree. What problem are you actually trying to solve?

Re: Get Entire Command Line of a Program
by mr_mischief (Monsignor) on Oct 14, 2010 at 21:12 UTC
    There are certain OS-specific ways to get that data from somewhere. They neither require Perl nor are fulfilled by Perl. They can be used from Perl or from many other languages, but only on the specific OSes that support them. Why specifically do you need it, and wouldn't it be better if that didn't matter to your program in the first place?
Re: Get Entire Command Line of a Program
by kcott (Archbishop) on Oct 20, 2010 at 03:14 UTC

    As noted, you can get your commandline arguments, except for IO redirection, via @ARGV.

    Whatever IO redirection has been specified is available within your Perl script via STDIN, STDOUT and STDERR.

    Here's how you can get at the filenames:

    $ perl -wE 'use IO::Handle; my $inode = (*STDERR{IO}->stat)[1]; say `f +ind -inum $inode`;' 2> derf ./derf $ perl -wE 'use IO::Handle; my $inode = (*STDOUT{IO}->stat)[1]; say `f +ind -inum $inode`;' > fred; cat fred ./fred

    That obviously needs substantial error checking and other work for a serious script but hopefully it's at least a start in right direction.

    -- Ken

Re: Get Entire Command Line of a Program
by HalNineThousand (Beadle) on Oct 20, 2010 at 01:18 UTC

    I have a script that will stay in the background and handle a loop every minute. In the past, I've had trouble with some scripts having memory issues after running like this for too long, so I figured one easy way to handle it would be to grab the command line when first run and save it, then after a few hours, just exec() that same line and die, leaving a new instance running.

    It was just an idea of a new way to be lazy (hey, doesn't Larry Wall encourage that?), rather than checking individually for each argument and reconstructing the command line and perhaps trying to reconstruct any IO redirection as well. It's not a "have to" thing, just an idea that it seems clear won't work.

    I know I can use a loop in a Perl or bash script to just relaunch every time the program dies, but I figured this might be more self contained.

    Since it's not something I can count on, there are other ways to do it. I just thought it might lead to some easy and possibly interesting little tricks of it could work.

    Thanks for the help on this!

      Won't this pretty much do what you're asking for?:

      ... if( some condition ) { ## fork and exit; ## Update: redundant exec $^X, $0, @ARGV; }
        I was hoping to also get anything like IO redirection, but I see from other responses that's not possible. Otherwise, it would do it. Thanks.
Re: Get Entire Command Line of a Program
by aquarium (Curate) on Oct 15, 2010 at 05:03 UTC
    maybe using the magick <> operator might help you to do what you want; or maybe not. it allows you to read/process all args as files to be sequentially read/processed OR if none specified you'll be reading/processing whatever input was piped/directed to the perl script.
    othewise, as has been already said, the shell or command line do a lot of evaluation etc of the line before perl is even called and args from line passed to it..so that perl has a very limited view of what the original shell/command line was.
    the hardest line to type correctly is: stty erase ^H