Reputation: 21
I'm having an issue with some code and I'm wondering if anyone can assist.
Basically I'm trying to execute an isql query against a database and assign it to a scalar variable. The isql command makes use of the column seperator which is defined as the pipe symbol.
So I have it set-up as such:
my $command = "isql -S -U -s| -i";
my $isql_output = `$command`;
The isql command works in isolation but when issued as a backtick it stops at the pipe. I've tried concatenating the $command
string using sub-strings, using single quotes and backslash escaping items such as -s\"\|\"
to no avail. I've also tried using qx
instead of backticks.
Unfortunately I'm currently using an older version of perl (v5.6.1) with limited scope for upgrade so I'm not sure if I can resolve this.
Upvotes: 2
Views: 5850
Reputation: 8591
The problem is that the command is being executed through a shell.
You can avoid this by passing the command and arguments in a list rather than a single string.
The backtick construct does not support that, so you would need to use the open()
function instead.
I haven't tested the following code but it gives the idea:
my @command = (qw(isql -Sserver -Uuser -Ppassword -s| -w4096), '–i' . $file);
print join(' ', @command), "\n";
open(my $fh, '-|', @command)
or die "failed to run isql command: $@\n";
my @isql_output = <$fh>;
close($fh);
my $isql_output = $isql_output[0]; chomp($isql_output);
If you're working with a 15 year old version of Perl (which Oracle users tend to do) I'm not sure this will all be supported. For instance, you may need to write chop
instead of chomp
.
UPDATE: the problem is not the Perl version, but this construct not being supported on Windows, according to the documentation. This must be qualified: I use Perl on Cygwin and it works fine there, but I don't know whether you can use Cygwin.
Upvotes: 1
Reputation: 745
Single quotes should work. Try to run test perl script:
my $cmd = "./test.sh -S -U -s '|' -i";
print `$cmd`;
With test.sh:
#!/bin/sh
echo $@
Output should be -S -U -s | -i
Upvotes: 0
Reputation:
You have to quote the |
in a way that the shell does not recognize it as a special character. Two ways:
-s|
into single quotes: '-s|'
. Perl will leave single quotes inside double quoted strings alone and pass them to the shell unmodified.|
with two backslashes: -s\\|
. Why two? The first one is seen by Perl telling it to pass the next character through unmodified. Therefore the shell sees -s\|
and does something very similar: it sees the single \
and knows not to treat the next char, |
, special.Upvotes: 4