Beefy Boxes and Bandwidth Generously Provided by pair Networks Russ
Welcome to the Monastery
 
PerlMonks  

Replacing backticks with system() and redirecting STDERR to file

by siva_kumar25 (Pilgrim)
on Jan 09, 2007 at 06:54 UTC ( [id://593702]=perlquestion: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.

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

Hi Monks,

Currently I am facing a problem in the below perl one liner code which is present in a perl script. 1) In this i would like to replace that "`"(backticks) with system() so that i can capture the status of the command and also would like to redirect the STDERR to the ssh'd node. Other parts of the code working fine. I have error only this part of the code.

my $command = 'ssh '. $node . ' "perl -e \'while (<>) { chomp; \$_ =~ +/(.*)\\//; \`su xxx -c \"mkdir -p \$1\"\`; \`su xxx -c \"touch \$_\"\ +`;}\' 1>>$storageRootPath_log 2>>$storageRootPath_err"'; my $pid = open ( $sshNodeStdinHandle{$node} , "| $command 2>>sivakumar +" ); #SK004 print {$sshNodeStdinHandle{$node}} /x/y/z/sample.txt,"\n";
2) If $storageRootPath_log is replaced with actual path, it's working fine. But if i use path assigned to the variable $storageRootPath_log ($storageRootPath_log = '/x/y/a/log.txt'), it is not working. I spent the whole day in this issue (tried by escaping double quotes etc.), but i could not able to solve. So can you peopel please help me to resolve this issue.

Thanks & Regards,
R.Sivakumar

Replies are listed 'Best First'.
Re: Replacing backticks with system() and redirecting STDERR to file
by gaal (Parson) on Jan 09, 2007 at 07:03 UTC
    Take a look at IPC::Run for this kind of thing in general. Or specifically for SSH, look at Net::SSH.
Re: Replacing backticks with system() and redirecting STDERR to file
by jettero (Monsignor) on Jan 09, 2007 at 07:06 UTC

    That's a little confusing to read, but it looks like you can exploit the 4-arg usage of open(): FILEHANDLE,MODE,EXPR,LIST. The reason it'll help is that you don't need to escape anything. I'm not 100% on that, but I'm pretty sure open will do a popen() directly when you use this format (rather than forking to a shell first). The docs do state that it may not work like I expect on all platforms.

    open $sshNodeStdinHandle{$node}, "|-", "ssh", $node, qq(perl -e ...... +..) or die "couldn't open pipe: $!";

    I'm pretty sure open doesn't return a pid, so I hope that isn't a problem. Otherwise you might need to look at IPC::Open3 or the like. UPDATE: It really does return a pid, but it's the pid of the shell for the two arg open and the pid of the process for the 4 arg version. Strange. I don't think that's documented, so I wouldn't count on it, but that's interesting anyway.

    -Paul

Re: Replacing backticks with system() and redirecting STDERR to file
by bart (Canon) on Jan 09, 2007 at 07:11 UTC
    my $command = 'ssh '. $node . ' "perl -e \'while (<>) { chomp; \$_ =~ /(.*)\\//; \`su xxx -c \"mkdir -p \$1\"\`; \`su xxx -c \"touch \$_\"\`;}\' 1>>$storageRootPath_log 2>>$storageRootPath_err"';
    The problem I see is that your variables are still in single quotes. Use double quotes and escape the embedded double quyotes, or rather, use qq() to properly interpolate the values. Something like (untested):
    my $command = 'ssh '. $node . qq( "perl -e 'while (<>) { chomp; /(.*)\ +\//; `su xxx -c \\"mkdir -p \$1\\"`; `su xxx -c \\"touch \$_\\"`;}' 1 +>>$storageRootPath_log 2>>$storageRootPath_err");
    Note how you don't need to escape that much this way — but an embedded backslash needs to be doubled.
Re: Replacing backticks with system() and redirecting STDERR to file
by ikegami (Patriarch) on Jan 09, 2007 at 10:39 UTC
    ow! That's not maintainable, assuming it's even correct. Create a script (preferably in advance, but dynamically might work) and see if you could call it using system PROGRAM, LIST to avoid quoting problems. Avoid the headaches!
Re: Replacing backticks with system() and redirecting STDERR to file
by jwkrahn (Abbot) on Jan 09, 2007 at 15:13 UTC
    You can eliminate a lot of the backslashing by using alternative delimiters:
    my $command = 'ssh ' . $node . q[ "perl -lne'm!(.*)/! && qx[su xxx -c +\"mkdir -p \$1\" && su xxx -c \"touch \$_\"]'] . qq[ 1>> $storageRoot +Path_log 2>> $storageRootPath_err"];

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://593702]
Approved by jettero
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.