http://qs1969.pair.com?node_id=556926

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

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re: find the shell inside a perl script
by Fletch (Bishop) on Jun 22, 2006 at 16:12 UTC

    You need to step back and say what you're trying to accomplish.

    If you want some commands to run with a specific shell, explicitly run that shell.

    If this is something that's output is being fed back to a parent shell (e.g. you're sourcing the output from it to set environment variables) the way I've seen most things behave is to presume the shell is Borne-ish unless a flag (say, -c) is given on the command line (in which case it spits out csh-y output).

Re: find the shell inside a perl script
by Tanktalus (Canon) on Jun 22, 2006 at 16:09 UTC

    It is possible to fool $ENV{SHELL} into thinking it's something other than the right answer. So I was going to mention using Proc::ProcessTable or something, combined with $$, to see what your parent process was, and check what that command was, etc., until you found a shell. But two things stop me from actually suggesting it. First, your program may be run from another program from another from the cron daemon, which is owned by init. So there may not be an obvious shell (it's there, but you may not be able to easily find it). Or your parent process may have died, and you got inherited by init.

    So, I second the vote on $ENV{SHELL}. If some advanced user wants to fool you into thinking the shell is csh when it's really bash, well, they may actually know what they're doing. Let them. If it's not set, ask that it be set - or have a reasonable fallback, whatever that means to your program.

    Although, I have to admit some curiosity - what are you doing that you care what the shell is? The only thing I can think of is that you're printing out a bunch of environment-setting commands, and you want to know whether to "setenv" or "export" them so that a parent shell could say exec `set_env.pl`.

Re: find the shell inside a perl script
by ikegami (Patriarch) on Jun 22, 2006 at 15:55 UTC

    `echo \$0` should always return sh. Backticks, system and exec use sh (on platforms with that shell).

    You want $ENV{SHELL} on unix OSs and $ENV{COMSPEC} in DOS/Windows.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: find the shell inside a perl script
by graff (Chancellor) on Jun 23, 2006 at 02:30 UTC
    From the command line if I execute echo $0, I will be able to find the shell name. How can I find this inside a script whithout using `echo $0`. I think there is no use of this command inside a perl script.

    You mean there's no point trying to use `echo $0` from inside a perl script, because that will never give you the information you need (as indicated by an earlier reply).

    You could get the return value from the getppid function call -- this would be the pid of the shell that is running the perl script -- and then you would have to look up that pid in the system's process table to figure out the command name associated with it. That would require either a special module for looking up the process table on your particular OS, or else running "ps" in backticks to get the command name. Something like this seems to work for me (on bsd-based macosx):

    my $ppid = getppid; my $ppdescrip = `ps -p $ppid`; my ( $shell_name ) = ( $ppdescrip =~ /(\S+)\s*$/ ); # shell name is last word in the output of "ps -p pid"
    I expect the ps command line, and/or where to find the shell name in the ps output, might vary slightly depending on your particular OS (and your script knows what OS you have: look for the "$^O" variable in perlvar).

    And of course, the only time this might fail is when the perl script has been invoked by something other than a shell. But I assume that will never be relevant in your case.

    (update: I'm still curious about what sorts of things you could possibly be doing inside the perl script that need to depend on which flavor of shell was used to run the script.)

Re: find the shell inside a perl script
by mikeock (Hermit) on Jun 22, 2006 at 16:11 UTC
    I would follow the other post but the if would be 1 rather than 3 different ifs.
    if ($shell_name eq 'bash'){ # do stuff here }elsif($shell_name eq 'ksh'){ # do stuff here }elsif($shell_name eq 'csh'){ # do stuff here }
    Update: I now look smart as his post has been updated!
    My sig Sucks!