Home > OS >  Does PHP shell_exec add parentheses to the command?
Does PHP shell_exec add parentheses to the command?

Time:06-13

I'm trying to run a cat command using the shell_exec function, to be more precise something like this:

cat <(echo "foo") bar.xml > foo-bar.xml

But I'm getting a syntax error like the following one:

sh: 1: Syntax error: "(" unexpected

I'm completely lost since this works fine locally and when the command is executed manually in the server, but when running the php script it returns the syntax error. Any clues?

Original code being used:

$shell_cmd = "cat <(echo \"{$this->xmlHeader}\") ";
$shell_cmd .= '\'' . $path . $filename . '\'' . " ";
$shell_cmd .= " > " . '\'' . $path . "hfb/" . strtolower(str_replace($this->replace_values, '', $hfbName)) . ".xml" . '\'';
shell_exec($shell_cmd);

CodePudding user response:

The problem here is likely to be which shell is used. It's not really documented, but I believe shell_exec will use /bin/sh, which will often be a minimal Posix-compliant shell (or a more complex shell emulating that compliance). That's very useful, because it means system scripts will always work the same way, regardless of what other shells are installed or configured for particular users.

When you log in directly, however, you're probably using bash, which has extra features such as the <(...) syntax for getting a named file descriptor from a command.

The best approach in this case is to make your command use only standardised facilities, which will be available in /bin/sh.

In particular, you are using cat to glue together a literal string from echo and a file:

cat <(echo "foo") bar.xml

That can be expressed instead by first echoing the string, and then outputting the file:

echo "foo"; cat bar.xml

To gather both into one output, place them in braces:

{ echo "foo"; cat bar.xml; } > foo-bar.xml

Alternatively, you can give cat an argument of - to concatenate standard input with one or more other files, so you could pipe the value from echo into it:

echo "foo" | cat - bar.xml > foo-bar.xml
  • Related