simonmichael / shelltestrunner

Easy, repeatable testing of CLI programs/commands
GNU General Public License v3.0
130 stars 10 forks source link

Incorrect escape of single quote #15

Closed bawolk closed 4 years ago

bawolk commented 5 years ago

In bash, a single-quoted string cannot contain a single quote even if it is escaped. However, single quotes can be included in a string of the form $'string' if they are escaped. I have an executable, hsp, that expects a single-quoted string. The following command works fine at the bash prompt and produces the expected output foo:

$ echo $'foo\nbar' | hsp $'\'o\' `elem` p'
foo

However the following test fails:

hsp $'\'o\' `elem` p'
<<<
foo
bar
>>>
foo
>>>= 0

Using debug I get the following:

command was: "hsp $'\\'o\\' `elem` p'"
stdout was : ""
stderr was : "/bin/sh: 1: Syntax error: Unterminated quoted string\n"
exit was   : "2"

It looks like shelltestrunner is double escaping the single-quote, thereby creating a syntax error, when it should leave unchanged the single escape of the single-quote inside the form $'string".

simonmichael commented 5 years ago

Thanks for the bug report. Would you be interested in trying to fix ? I'd be happy to help with tooling etc., in #shelltestrunner @ Freenode.

obfusk commented 5 years ago

The problem is not with shelltestrunner (the double escapes are from show), but with the difference between /bin/sh and /bin/bash.

With the --shell option I just proposed:

$ cat x.test 
echo $'\'o\' `elem` p'
>>>
'o' `elem` p
>>>= 0
$ cabal run shelltest -- x.test 
Up to date
:x.test: [Failed]
Command (at line 1):
echo $'\'o\' `elem` p'
Expected stdout: 
'o' `elem` p

Got stdout:      
Expected exit code: 
"0"
Got exit code:      
2

         Test Cases  Total      
 Passed  0           0          
 Failed  1           1          
 Total   1           1          
$ cabal run shelltest -- x.test --shell /bin/bash 
Up to date
:x.test: [OK]

         Test Cases  Total      
 Passed  1           1          
 Failed  0           0          
 Total   1           1          

FYI: this does work in /bin/sh:

$ echo \''o'\'' `elem` p'         
'o' `elem` p