ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am trying to fix a perl script, and I really suck at perl. But I think this problem will be easy for people who know it.
The problem is, I have an old setup script someone wrote many years ago. It fails if the standard shell is dash and not bash. The only way I've gotten it to work is to point /bin/sh to bash. I looked thru the script and it uses "system" many places, and I think that's the problem.
sub system_bash {
my @args = ( "bash", "-c", shift );
system(@args);
}
Then I could simply change all calls to system into system_bash and it should work?
The parameter to the system calls is usually some variable. What if the parameter is a list already? Do I need to test for it somehow, and if it's a list, prepend "bash" and "-c" to the list? How do I do that?
In the script there are lots of places like this:
my $error = system($cmd);
if ($error) {
die/warn "some error message";
}
Shouldn't there be a return in the system_bash function?
My first instinct would be to stop using 'system()' if it has any dependency on a particular shell, and since anything you can do with Bash you can probably do easier & better with Perl. If it needs to call other stand-alone applications, these can be invoked from Perl in any number of ways.
I haven't tried this, but you may be able to coerce Perl to use Bash by default in system() calls, simply by setting the $SHELL environment variable to "bash".
The problem is that the script is long and complicated - reading lots of config files and things. The person who wrote it was fairly good at Perl, so I figured he didn't use system if it was uneccessary. But when he wrote it, there was no dash, and as I said, if bash is standard shell, it works fine.
Setting $SHELL in the script doesn't seem to work. I tried this code:
This too works fine if /bin/sh points to bash, but not when it's dash. Or does Perl need something like export? It looks like "/bin/sh" is hard-coded in Perl somewhere.
This too works fine if /bin/sh points to bash, but not when it's dash. Or does Perl need something like export? It looks like "/bin/sh" is hard-coded in Perl somewhere.
Yes, it looks like it. I just tried invoking perl from a csh commandline, with $SHELL set to 'csh', and it still invoked dash (Debian). Sorry to have sent you on a tangent.
Incidently, setting environment variables in Perl is done by writing to the %ENV hash.
The problem is that the script is long and complicated - reading lots of config files and things. The person who wrote it was fairly good at Perl, so I figured he didn't use system if it was uneccessary. But when he wrote it, there was no dash, and as I said, if bash is standard shell, it works fine.
Setting $SHELL in the script doesn't seem to work. I tried this code:
This too works fine if /bin/sh points to bash, but not when it's dash. Or does Perl need something like export? It looks like "/bin/sh" is hard-coded in Perl somewhere.
First of all, you are doing it wrong - see a post above about '%ENV'; secondly, according to my experiments, Perl ignores $SHELL - it looks like '/bin/sh' is hard-coded into it. I am not even sure this can be changed when Perl is built from sources, but one can find '/bin/sh' in whatever Perl source files and replace it with desired path to shell.
Good point Sergei. I grepped a bit in the code without finding anything. And the script is meant to setup/upgrade some software, and I searched thru it without finding any shell scripts. There is no mention of "bash" or "bin/sh" anywhere. But there are some use of open, and I think some of them can be like popen, so I will have to look thru those.
But back to that system_bash function. Is there anyway to make it accept a list as parameter instead of just a string? I tried this, but it doesn't work:
Code:
sub system_bash {
my @args = ( "bash", "-c", shift );
return system(@args);
}
my @cmd = ("echo", "1", "2", "3");
my $retcode = system_bash(@cmd);
It is easy enough to just use join() to make a whitespace delimited string.
Code:
sub system_bash {
my @args = ( "bash", "-c", shift );
return system( join( " ", @args ) );
}
I'm glad Sergei was able to confirm that modifying $ENV{"SHELL"} doesn't affect how Perl loads a shell; I thought I had gone a bit soft in the head. Still seems an odd and counter-intuitive behavior.
One could manufacture their own system() function clone, but I wouldn't do it the way the OP suggested, since that appears to make the problem recursive. My solution, if I had to use system() at all (and I never prefer to), would be to use a fork() + exec() + wait(). From what I've observed, most/many people use system(), which loads a shell in order to simply load some other program which could have been loaded directly. If you really do need bash instead of dash, you can launch it this way.
Code:
sub mySystem{
if( my $childPid = fork() ){
wait;
}
else{
exec( @_ );
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.