0

I have a php script that passes a variable to a bash script:

exec("bash.sh $path")

The bash script looks like so:

#!/bin/bash
path=$1

echo $path

If the path ends in dollar signs like so: myfile.$$$

The output is: myfile.32577$

How can I escape the dollars in the variable, so that the echo is accurate?

ilkkachu
  • 138,973
Lee
  • 149

2 Answers2

4

PHP's exec() executes the command through a shell, so even before your script runs, there's a shell that processes the command line. $$ in the shell is a special variable for the process id of the shell, but you'd get the same for anything else that looks like it could be a variable.

The PHP manual for exec explicitly reminds to quote the command or the arguments for shell processing:

Warning
When allowing user-supplied data to be passed to this function, use escapeshellarg() or escapeshellcmd() to ensure that users cannot trick the system into executing arbitrary commands.

I can't find a version of system()/exec()/others that would allow running a command directly (like the multi-argument version of system()/exec() in Perl), so it may be that the only option is to use escapeshellarg(). It quotes the argument with single quotes and handles single quotes too.

$ php -r '$foo="$$$"; system("/bin/echo $foo");'
21836$

$ php -r '$foo="$$$"; system("/bin/echo " . escapeshellarg($foo));'
$$$

(You could use escapeshellcmd() to quote the whole script, but I'd avoid situations where that's required: the shell language is complex enough that there's a good chance the quoting will fail at some obscure case.)


Also, as Kusalananda mentions, (and as usual) you still want to quote the variables in your Bash script too. So use echo "$path" rather than echo $path. The dollar sign is not a problem here, whitespace and glob characters are.

See:

ilkkachu
  • 138,973
  • $$ would be an issue though ;-) – Kusalananda Jul 09 '18 at 10:05
  • @Kusalananda, err, I may be missing the joke here. The $$ won't be expanded from the contents of $path, quotes or not. E.g. with foo=$$; echo $foo, the problem is the assignment, not the expansion. Right..? (Of course if they literally write $$ in their script, then that's their problem.) – ilkkachu Jul 09 '18 at 10:13
  • Duh. Right you are. Also, send more coffee... – Kusalananda Jul 09 '18 at 10:23
  • 1
    I'd have one sent to you, if SE implemented that feature. – ilkkachu Jul 09 '18 at 10:31
0

In case that this exec feature in php is implemented via sh -c cmd, you need to call:

 exec("bash.sh '$path'")

inside your shell script, there does not seem to be a problem, since $$ would only be expanded if you did use eval.

Kusalananda
  • 333,661
schily
  • 19,173
  • 1
    Single-quoting's not good enough against hostile attempts. For instance, anybody manages to set a filename to myfile';rm -rf ~;'.$$$, ... You need to escape internal singlequotes with something like sed -z "s,','\\\'',g;s,.*,'&',". – jthill Jul 09 '18 at 12:40