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

I have come across a bit of trouble with making a system call that involves a semicolon. I am doing a backtick system call in the following fashion:
my $output = `/usr/sbin/ubsetenv $currParam $formValue`;
$currParam is the name of the parameter and $formValue is the value to set the parameter to.

It works fine when $formValue doesn't have any semicolons, but when I put in an escaped semicolon (\;) to be used as the argument, it fails with no output. Note: semicolon is escaped for the purpose of the shell script, not perl.

An example input that causes it to fail is: boot0\;boot1

I have verified that the input from the form is making it to the parsing script intact and have tried storing it to a variable first and viewing the command before executing the command with backticks around the variable. It appears that everything is making it fine up until the backtick command is called, at which point something happens causing it to fail.

Is there something weird about the use of backticks with semicolons that I have missed? Does anyone have any suggestions? Any help would be greatly appreciated.

Replies are listed 'Best First'.
Re: system call with semicolon in argument
by ikegami (Patriarch) on Sep 16, 2009 at 02:14 UTC

    You failed to convert your program's arguments into shell literals when you built your shell command. You're lucky someone didn't pass `rm -rf /` for $formValue! People need to think before inserting a string into another.

    The simplest fix is to avoid the shell:

    open(my $fh, '-|', '/usr/sbin/ubsetenv', $currParam, $formValue) or die("fork: $!\n"); local $/; my $output = <$fh>;
      I was already escaping the backslash as LanX mentioned. I ended up using ikegami's solution, which worked great and also doesn't require escaping the semicolon in the input. It is definitely a better and safer solution than what I was using before.
Re: system call with semicolon in argument
by LanX (Saint) on Sep 16, 2009 at 01:59 UTC
    I don't think it's a perl problem:

    Your semicolon is interpreted as command delimiter by the shell. You should consider either quoting or escaping "twice"!

    DB<1> print `echo '\;'` ; DB<2> print `echo \;` DB<3> print `echo \\;` ; DB<4> print `echo ';'` ; DB<5> print `echo '\\'` \

    To be more precise you have to escape the backslash for perl not the semicolon, such that the shell finally sees an escaped semicolon \;. As you can see by comparing line 1 and 4 escaping the semicolon has no effect for perl!

    \; and ; are identical, since there is no special meaning like for \n

    Cheers Rolf