Reputation: 3479
Here's my code
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my $file = $ARGV[0];
system('wc -l $file');
print "\nprinting alpha \n";
sleep 1;
exit;
After I run (in tcsh
shell) perl script.pl /path/to/file
I don't see printing alpha
until I press Ctrl+C
. Even when I add another statement $|=1
either before or after system call, the behaviour remains the same.
What is happening?
Upvotes: 0
Views: 144
Reputation: 386206
You are executing the shell command
wc -l $file
The shell has no variable $file
defined, so that's the same as
wc -l
This causes the shell to execute wc
with the lone arg -l
. With no file name provided, wc
in turn reads from STDIN until you kill it with SIGINT from Ctrl-C.
You were perhaps aiming for
system("wc -l $file"); # XXX
but that's wrong too. That doesn't pass the args -l
and the value of $file
to wc
. Consider what would happen if a file name with a space in it was provided.
To build a shell literal that results in the correct file name, you could use
use String::ShellQuote qw( shell_quote );
system(shell_quote('wc', '-l', $file));
But a better option is to avoid the shell and execute wc
directly, passing to it the values you want without having to build a shell command.
system('wc', '-l', $file);
Upvotes: 4
Reputation: 86774
Because the single quotes prevent interpolation of $file
. Change to double quotes.
What is happening is that the string is being executed without substituting a value for $file
. When the shell gets this it looks for a shell variable $file
which does not exist, so it executes the command with no file. This causes wc
to read from stdin, resulting in the behavior you see.
Upvotes: 1