Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing command to shell

Status
Not open for further replies.

fmri

Programmer
Oct 31, 2008
1
US
Code:
sub flirtReg {

# Perform registration in Flirt                                                                                                               
# Check the wd for the files we need                                                                                                          

# keys: (identifiers); values: filenames                                                                                                      

    my %F_PARS = ("brain","", "structural","", "lvent","", "rvent","");

    my $N_EX='.nii';
    my $NGZ_EX="${N_EX}.gz";

    my $FLIRT="/Applications/fsl/bin/flirt";
    my $PASS1_FLAGS='-bins 256 -cost corratio -searchrx -180 180 -searchry -180 180                                                           
         -searchrz -180 180 -dof 12 -interp sinc -sincwidth 7 -sincwindow hanning';

# Build file array                                                                                                                            

    foreach (keys %F_PARS) { die "error: file \`${_}$NGZ_EX\' not found" if !($F_PARS{$_}=`ls|grep ${_}$NGZ_EX`); }

# Run command $FLIRT with the options that follow 
# (i.e., `/Applications/fsl/bin/flirt -in <structural-filename>\
# -ref <brain-filename> ...                                                                                                                             

    my $F_PASS1=qq/$FLIRT -in $F_PARS{"structural"} -ref $F_PARS{"brain"} -out $F_PARS{"structural"}_CSF_prior$NGZ_EX -omat ${SUBJ}_CSF_prior\
.mat $PASS1_FLAGS/;

# doesn't work

    system ($F_PASS1);

    
}

output:
Code:
sh: line 1: -ref: command not found
sh: line 2: -out: command not found
sh: line 3: _CSF_prior.nii.gz: command not found
sh: line 4: -searchrz: command not found

I want to pass the `flirt' command to the shell. How do you do that without the shell interpreting the arguments as separate commands? Sorry about the word-wrapping; hopefully the context is clear.
 
Firstly, you should be very careful with that. The results you're getting about the shell interpreting arguments as separate commands is a hint to how tricky it can be sending shell commands within Perl.

You need to organize your command in a way that if you typed the command on the shell in the same way Perl's going to, that it'll work.

So you'd want to quote all arguments that might contain spaces or pipes or any other tricky characters, and then escape any characters within that would contradict your quotes.

Probably safest to use single quotes (so that they can't try to interpolate $ENVIRONMENT_VARIABLES in)...

Code:
# example... for a `mv` command...
# mv $from $to
my @args = (
   "/media/ntfs/Documents and Settings/file.txt",
   "/home/myname/file from windows' drive.txt",
);

# filter the arguments
foreach my $arg (@args) {
   # Escape any single quotes
   $arg =~ s/\'/\\'/g;

   # wrap the arg in single quotes
   $arg = qq{'$arg'};
   # $arg = "'$arg'"; works too but its
   # easier to read with qq{} I think
}

# Now we can be reasonably confident when
# feeding this to the system. And to make
# sure it's sending the right data, print
# it to the terminal too.
my $cmd = "mv $args[0] $args[1]";
print "Exec: $cmd\n";
system($cmd);

With any luck it would print

Code:
Exec: mv '/media/ntfs/Documents and Settings/file.txt' '/home/myname/file from windows\' drive.txt'

-------------
Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top