2

In PHP, I have a variable that returns a multi-line text, similar to what is displayed below.

*
*clefF4
*k[f#c#g#d#a#]
*d:
*M6/4

I then want to use this variable in PHP as an argument to execute a bash script. My PHP code for doing so is below (Where $filechosen is the string of text above):

$output = shell_exec("/path/to/bash/script.sh $filechosen");
echo "<pre>$output</pre>";

Below is that extremely simple bash script that uses the variable '$filechosen' as an argument:

#!/bin/bash

returnExpression=$(echo "$1" | grep 'k\[')
echo $returnExpression

However, when I run this, I get no output. Why is this?

2 Answers 2

2

You should always escape variables that you're substituting into command lines, and PHP provides a function escapeshellarg() to do it.

$output = shell_exec("/path/to/bash/script.sh " . escapeshellarg($filechosen));

or

$escaped = escapeshellarg($filechosen);
$output = shell_exec("/path/to/bash/script.sh $escaped");
Sign up to request clarification or add additional context in comments.

8 Comments

With slight modification, this worked! Thank you very much.
What was the modification?
For some reason, the syntax in the answer wasn't working, so I set a separate variable, filechoose: $filechose = escapeshellarg($filechosen); Then the execution of the script was changed to this: $output = shell_exec("/path/to/bash/script.sh $filechose");
There really shouldn't be any difference between concatenating variables and substituting into the string. Did you remember to leave a space after .sh when you concatenated?
I did. For some reason, it still isn't working with concatenation.
|
1

In GNU/Linux the common way of commands is to process streams. Also grep does so. Whenever possible, you should not break this pattern. In your paricular example it does not make sense to wrap it into positional parameters.

You can use popen to write a stream to the executed command:

<pre>
<?php

$filechosen = <<<_EOS_
*
*clefF4
*k[f#c#g#d#a#]
*d:
*M6/4
_EOS_;


if($handle = popen("grep 'k\\['", "w"))
{
  fwrite($handle, $filechosen);
  pclose($handle);
}

?>
<pre>

Use proc_open function instead when you want to read the output stream into a variable.

if($handle = proc_open("grep 'k\\['", [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $streams))
{
  [$stdin, $stdout, $stderr] = $streams;

  fwrite($stdin, $filechosen);
  fclose($stdin);

  $output = stream_get_contents($stdout);
  fclose($stdout);

  $error  = stream_get_contents($stderr);
  fclose($stderr);

  proc_close($handle);
  echo $output;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.