Re: Specifying a shell for use with Backticks
by zentara (Archbishop) on Apr 11, 2006 at 20:01 UTC
|
I know you asked about backticks, but an alternative would be to use IPC::Open3, then you could specify whatever shell you want to run your script.
#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;
$|=1;
#my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/bash');
my $pid=open3(\*IN,\*OUT,0,'/bin/bash');
# set \*ERR to 0 to send STDERR to STDOUT
my $cmd = 'date';
#send cmd to bash
print IN "$cmd\n";
#getresult
my $result = <OUT>;
print $result;
I'm not really a human, but I play one on earth.
flash japh
| [reply] [Watch: Dir/Any] [d/l] |
Re: Specifying a shell for use with Backticks
by derby (Abbot) on Apr 11, 2006 at 19:27 UTC
|
There's no way of overriding backtick (or qx) that I know of ... and by default it should be using some bourne shell variant not csh (but I guess it all depends on what type of wackiness your system was in when perl was built - I've seen plenty of systems where sh was really csh). I think you're going to be better off with fork and exec -- modified from the code in perlsec:
#!/usr/bin/perl
use English '-no_match_vars';
my $content = mysystem( "/bin/ls", "-l" );
print $content;
sub mysystem {
my @args = @_;
my $pid;
my $content;
die "Can't fork: $!" unless defined($pid = open(KID, "-|"));
if( $pid ) { # parent
while (<KID>) {
$content .= $_;
}
close KID;
$content;
} else {
my @temp = ($EUID, $EGID);
my $orig_uid = $UID;
my $orig_gid = $GID;
$EUID = $UID;
$EGID = $GID;
# Drop privileges
$UID = $orig_uid;
$GID = $orig_gid;
# Make sure privs are really gone
($EUID, $EGID) = @temp;
die "Can't drop privileges"
unless $UID == $EUID && $GID eq $EGID;
$ENV{PATH} = "/bin:/usr/bin"; # Minimal PATH.
# Consider sanitizing the environment even more.
exec @args
or die "can't exec: $!";
}
}
Since no shell is being used, just ensure you have your environment the way you want before calling the code (and please beef this sample up ... it does no error checking nor return value checking).
| [reply] [Watch: Dir/Any] [d/l] |
Re: Specifying a shell for use with Backticks
by fletcher_the_dog (Friar) on Apr 11, 2006 at 19:23 UTC
|
You can specify enviornment variables for commands done in backticks by using the special %ENV hash, like this
$ENV{FRED}="JONES";
# this will print JONES
print `echo \$FRED`;
| [reply] [Watch: Dir/Any] [d/l] |
Re: Specifying a shell for use with Backticks
by merlyn (Sage) on Apr 11, 2006 at 20:16 UTC
|
Backticks are supposed to use /bin/sh, or the closest equivalent on your system. What evidence do you have that it's a csh variant instead?
| [reply] [Watch: Dir/Any] |
Re: Specifying a shell for use with Backticks
by hacker (Priest) on Apr 11, 2006 at 20:09 UTC
|
| [reply] [Watch: Dir/Any] |
Re: Specifying a shell for use with Backticks
by Zerhash (Scribe) on Apr 11, 2006 at 19:18 UTC
|
you could read the .profile for the path and set it in the perl script. or before you execute you can export the path variable | [reply] [Watch: Dir/Any] |
Re: Specifying a shell for use with Backticks
by Argel (Prior) on Apr 11, 2006 at 22:41 UTC
|
A kludge would be something like `/usr/bin/tcsh -c myscript`. | [reply] [Watch: Dir/Any] |
Re: Specifying a shell for use with Backticks
by Anonymous Monk on Apr 12, 2006 at 00:33 UTC
|
I am not really a power perl user but mostly shell user.
But I think the following idea will work.
Assuming that your "myscript" is indeed a cshell script
Try using
#! /bin/csh -f
as the first line in that file. Also Try reading
"UNIX power Tools by Jerry Peek, Tom O'Reilly,
Chapter 47 "Shell Programming for ..."
47.02 - 47.05 the story of #! to get good handle on
what shell get's used when you invoke a script.
Good luck
--- Rama Reddy ( Rama.Reddy@intel.com ) | [reply] [Watch: Dir/Any] |
Re: Specifying a shell for use with Backticks
by gaspodethewonderdog (Monk) on Apr 12, 2006 at 13:01 UTC
|
First I want to thank everybody for the comments.
We know for certain that it is picking up the .cshrc settings because when we remove the PATH statements all of the alternate commands are working properly, and hence my assumption that they are using csh when backticking commands in perl. Unfortunately some of the people here running the perl scripts need to have both special PATH and ENVIRONMENT settings for the perl tools as well as other tools, and they both conflict with each other. It is very much a chicken and egg problem.
Since we are getting both sets of tools from a corporate source repository, and we really are not at liberty to make changes to them that is why I was just hoping for a quick one change of code to change the backtick behavior that I could send of to HQ and hope that it would get implemented some day. Even though using the IPC modules is a good alternative, I doubt I'll be able to get somebody to change the implementation under the hood of these scripts.
Again, thank you all for posting. Even though I cannot do much in this case I will definitely check out IPC::Open3 and IPC::Run at least for my own scripts. Given how touch and go the environment is here I don't want to be adding to this very huge mess. | [reply] [Watch: Dir/Any] |
|
If you really can't get backticks to use a reasonable shell, perhaps you can trick it. For example in ksh, you can do something like this...
my $output = `PATH=$ENV{PATH} command arg1 arg2 argn`;
... which sets PATH just for the command. Just be careful you know what is in $ENV{PATH} (e.g. no spaces; not user supplied). I don't know if this syntax will work for csh also, so perhaps something ugly like... my $output = `setenv PATH "$ENV{PATH}"; command arg1 arg2 argn`;
An alternative, if you are only worred about the PATH, might be to supply a fullpath to backticks (i.e. dont give the shell a chance to locate it - just tell it)... my ($cp) = grep { -x $_ } map { "$_/cp" } grep { length $_ } split /:/
+, $ENV{PATH};
die "cant find cp" unless defined $cp;
my $output = `$cp source dest`;
IMO these seem like band-aids for the real problem. Using csh is just unsafe, outside of an interactive shell. | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Specifying a shell for use with Backticks
by bigmacbear (Monk) on Apr 12, 2006 at 17:20 UTC
|
I had a similar problem with a Makefile a long time ago. Make used whatever shell was in the user's environment rather than defaulting to a /bin/sh-like shell, and everybody used /bin/csh at the site. So I had to explicitly set $SHELL to /bin/sh in the Makefile.
Extrapolating to Perl, have you tried explicitly setting
$ENV{'SHELL'}=/bin/sh before running your backticks?
| [reply] [Watch: Dir/Any] [d/l] |
Re: Specifying a shell for use with Backticks
by mattr (Curate) on Apr 14, 2006 at 14:48 UTC
|
Just a shot in the dark but when you build perl, doesn't it ask you your preference, i.e. "Where is your preferred shell program?" In which case you could build another perl for your app. Sorry if this doesn't help though. I suppose you tried calling /bin/sh from inside the backticks but had trouble getting the result returned? | [reply] [Watch: Dir/Any] |