skip to Main Content

I’m trying to run a command at the command prompt and if one of the values includes a single quote it doesn’t run correctly.

The command I’m using is :

lxc-attach -n test -- bash -c 'echo 'abcd1234' > /home/rocket/test.log'

This will complete without issue and abcd1234 is written to the test.log correctly.

However if I run the command with abcd’1234 then the command doesn’t update the log file.

lxc-attach -n test -- bash -c 'echo 'abcd'1234' > /home/rocket/test.log'

I’ve tried escaping the ‘ with but that hasn’t helped.

Could someone advise how to get this to run.

Thanks

UPDATE I’m actually running this from a PHP page and using SSH to update the server. The actual command being run is:

$update = "echo $password | sudo -S lxc-attach -n $server -- bash -c 'echo "$value" >> /home/rocket/test.log'";
$ssh->exec( $update );

Where $value may contain a single quote.

3

Answers


  1. Chosen as BEST ANSWER

    I've managed to get this working.

    $value = str_replace( "'", "'''", $value );
    
    $update = "echo $password | sudo -S lxc-attach -n $server -- bash -c 'echo "$value" >> /home/rocket/test.log'";
    

    $value is now shown correctly in the log file.


  2. What I would do:

    lxc-attach -n test -- bash -c 'echo "abcd'1234" > /home/rocket/test.log'
    

    or:

    lxc-attach -n test -- bash<<'EOF'
    echo "abcd'1234" > /home/rocket/test.log
    EOF
    
    Login or Signup to reply.
  3. Since $password is completely arbitrary, you’ll want to use escapeshellarg on it to sanitize it.

    Since this is a complex command, you’ll need to use it multiple times, it’s the only way to be sure the inputs are completely sanitized. I’ve gone ahead and fixed the escaping on $value and $server too:

    $bash_command = 'echo ' . escapeshellarg($value) . ' >> /home/rocket/test.log';
    $update = 'echo ' . escapeshellarg($password) .
        ' | sudo -S lxc-attach -n ' . escapeshellarg($server) .
        ' -- bash -c ' . escapeshellarg($bash_command);
    
    $ssh->exec( $update );
    

    Cleaner solution using sprintf:

    $bash_command = sprintf('echo %s >> /home/rocket/test.log',
        escapeshellarg($value),
    );
    $update = sprintf('echo %s | sudo -S lxc-attach -n %s -- bash -c %s',
        escapeshellarg($password),
        escapeshellarg($server),
        escapeshellarg($bash_command),
    );
    $ssh->exec( $update );
    

    Doing this results in the sanitized string,

    echo 'abcd'''1234' | sudo -S lxc-attach -n 'example.com' -- bash -c 'echo '''hello world''' >> /home/rocket/test.log'
    

    And yes, that absolute mess IS how you need to phrase literal single quotes when used alongside single-quoted strings in shell. Hey look, even SO’s markdown parser has trouble with it. O__o Luckily you don’t need to care about manually doing it if you use escapeshellarg in my code above.

    I’m always paranoid about user-generated input ever since the Bobby Tables incident.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search