attamatti
attamatti

Reputation: 183

Perl: command works from shell but not system()

Rank beginner here please be gentle... I'm writing a program in perl that finds all of a certain file type and calls and another program called newstack to convert the file types.

When I run newstack oldfileame newfilename from my shell it works fine.

when my program runs system("newstack oldfileame newfilename") newstack returns the error:

ERROR: NEWSTACK - NO INPUT FILE SELECTED
sh: line1: ./oldfilename: cannot execute binary file

If I write a shell script that does the same thing, running newstack on the files one at a time it works fine. Is there something I'm missing here why it fails when run within the context of the perl program?

Newstack is from the IMOD suite of programs, I don't know what it's written in. The files are mrc files which are binary image files.

EDIT:: Here's the actual code as requested:

print "Enter the rootname of the files to be converted: ";
my $filename = <STDIN>;
chop $filename;

my @files = qx(ls $filename*.mrc);     
open LOGFILE, (">modeconvert-log");     
foreach my $mrc (@files)           
{        
print LOGFILE "$mrc";       
system("newstack -mode 2 $mrc $mrc");     
} 
my $fileno = @files;
print "$fileno files converted\n";

I added chop $mrc after line 8 and it fixed the problem

Upvotes: 2

Views: 1710

Answers (1)

ikegami
ikegami

Reputation: 385506

The code you posted and the code you executed differ. In the code you executed, there was a newline after newstack

$ perl -e'system("who\n oldfileame newfilename")'
sh: line 1: oldfileame: command not found

Remove the newline using chomp($x) or using $x =~ s/\s+\z//;.


my @files = qx(ls $filename*.mrc);

should be

my @files = qx(ls $filename*.mrc);
chomp @files;

Or better yet:

my @files = glob("\Q$filename\E*.mrc");

The above and other fixes:

use IPC::System::Simple qw( system );                          # Replaces system with one that dies on Checks for errors.

open(my $LOGFILE, '>', 'modeconvert-log')                      # Avoids global vars.
   or die("Can't create log file \"modeconvert-log\": $!\n");  # Adds useful error checking.

print "Enter the rootname of the files to be converted: ";
my $filename = <STDIN>;
chomp $filename;                                               # chomp is safer.

my @files = glob("\Q$filename\E*.mrc");                        # Works with file names with spaces, etc.

for my $mrc (@files) {
   print $LOGFILE "$mrc\n";                                    # Was missing a newline.
   system("newstack", "-mode", "2", $mrc, $mrc);               # Works with file names with spaces, etc.
} 

print 0+@files, " files converted.\n";

Upvotes: 2

Related Questions