Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

System() in list mode?

by 1337John (Initiate)
on Oct 17, 2011 at 20:51 UTC ( #932008=perlquestion: print w/ replies, xml ) Need Help??
1337John has asked for the wisdom of the Perl Monks concerning the following question:

Hello, long time lurker, first time poster. I'm trying to use system() in list mode like so:
my @a=("echo", "\$PATH"); system(@a);
However, I just get $PATH as output instead of the value of my path.
Background:
1. Linux.
2. I'm not actually echo'ing anything in my real code, but I can't even get this unit test to work. My code is supposed to set $PATH, then run a command on the same line, in the same shell.
3. Unless I can temporarily set my $ENV{PATH} variable without having to manually reset it, then don't tell me to use that. It makes no sense to me to set a global variable for a temporary shell. Apparently other-forum goers don't know about OOP.
4. I successfully did this using system() in scalar context (one string arguement, ok it's not actually scalar but w/e).
5. I'm trying to do this in order to handle spaces in path names (which shouldn't appear in linux but it's better safe than sorry). If another way can be used to resolve this issue then that works too!

Thanks

Edit:
Apparently monks can't read either. So far most of the answers provided are relevant to what I'm trying to achieve.
5. I'm trying to do this in order to handle spaces in path names (which shouldn't appear in linux but it's better safe than sorry). If another way can be used to resolve this issue then that works too!

Edit 2:
Ok here's my code. The second system call is supposed to set my PATH to something (it's actually something but not relevant; also, long), then run a script.
#!/usr/bin/perl -w use strict; use warnings; my $path = "/home/john/test/test a folder"; my @arr = ("echo", "\$PATH"); system (@arr); my @script = ("env", "PATH=\"foo\"", "bash", "$path/test.sh"); system (@script);
For output I get:
$PATH
env: bash: No such file or directory


Any help is appreciated. Bullsh*t not so much.

Comment on System() in list mode?
Select or Download Code
Re: System() in list mode?
by ikegami (Pope) on Oct 17, 2011 at 21:12 UTC

    First, it's not being called in list context. That means something else. I call this the multiple argument form.

    When you use the single argument form, system expects a shell command and will launch a shell to execute the command*, so

    system('echo $PATH');

    is the same as

    system('/bin/sh', '-c', 'echo $PATH');

    The shell expands $PATH, and in turn, does

    system('echo', '/foo:/bar');

    which is quite different than your

    system('echo', '$PATH');

    You must either use the shell

    system('echo $PATH');
    system('/bin/sh', '-c', 'echo $PATH');

    or you must do what it would do

    system('echo', $ENV{PATH});

    My code is supposed to set $PATH, then run a command on the same line, in the same shell.

    You should start by launching a shell, then!

    system('PATH=/foo prog arg');

    Or not. This is something you can do yourself quite easily.

    local $ENV{PATH} = '/foo'; system('prog', 'arg');

    * — As an optimisation, Perl avoids launching a shell when it's obvious that the shell isn't needed.

      Thanks for the reply. The explanation wasn't the best but eventually I got it to work this way.
Re: System() in list mode?
by onelesd (Pilgrim) on Oct 17, 2011 at 21:13 UTC
    4. I successfully did this using system() in scalar context (one string arguement, ok it's not actually scalar but w/e).

    When you use system with LIST context the subsequent command is not run in a shell. When you use it with one scalar argument the command is run in a shell.

      Well yea... it uses execvp(). Which should work no?
        There is no shell in LIST mode so setting a PATH variable doesn't have the effect you are looking for. You need to provide full paths to files/binaries, such as /bin/bash.

        Edit:

        No need to be an a$$ to people taking time out of their lives to help you.

Re: System() in list mode?
by RichardK (Priest) on Oct 17, 2011 at 22:06 UTC

    BTW -- You can have spaces in linux paths :)

    You just have to escape them on the command line with \

      Because I can obviously do that in the code I posted? Look through my variables each time and escape all the spaces before passing them to system()? I could. But I like to think that a) I know more perl than you and b) I'm not going to settle when there might be a better solution. I'm going to try and use that as a last resort.

        But I like to think that a) I know more perl than you

        Wow; where do you get off?

Re: System() in list mode?
by dd-b (Monk) on Oct 17, 2011 at 22:13 UTC

    The very first response seems to me to tell you everything you need to know -- your code doesn't work because the multi-argument form of system() isn't invoking a shell, so your "$PATH" isn't getting expanded, so it's just printing the characters dollar-sign, pee, ay, tee, aitch.

    And I concur that you're being quite rude to people who you seem to hope will help you. Especially since it looks to me like you're not reading the responses carefully enough to benefit from them.

Re: System() in list mode?
by anneli (Pilgrim) on Oct 18, 2011 at 09:29 UTC

    For output I get:
    $PATH
    env: bash: No such file or directory

    Where's the issue here? This is the correct output; the first system didn't expand $PATH (which we all know we all know about now), and in the second, you changed $PATH to foo and I guess you don't have a binary called foo/bash! If your PATH contained bash, using env PATH=... will work just fine.

    Anne

      What??? Of course it's the correct output for my code. But it's not what I want my code to do. Could you be so kind as to provide me with an example of appending to the PATH variable, then successfully running a script in a path with spaces in it, in one system() call?

        Alright.

        Here I'm prepending $HOME/dir to PATH, and executing a program named "program name", which happens to be in /home/anneli/dir (i.e. the path I prepended):

        $ pwd /home/anneli $ ls -F ./dir/ program name* $ cat dir/program\ name #!/usr/bin/env perl print "It works!\n"; $ cat eg.pl system('env', "PATH=$ENV{HOME}/dir:$ENV{PATH}", 'program name'); $ perl eg.pl It works! $

        I hope this helps. We do the necessary expansion of HOME and PATH on our side, before sending them through to the (non-expanding) multi-argument system call.

        Anne

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://932008]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2014-07-29 02:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (211 votes), past polls