Search code examples
linuxterminalsh7zip

Escape single quote in command argument to sh -c


I am trying to send a command to another terminal. I've learned that I need to use sh -c to send the entire command in once. The command itself is to compress a file using 7-Zip (command-line executable 7z). Here is an example:

7z a Aa.zip Bb.txt

So the entire command would be

sh -c '7z a Aa.zip Bb.txt'

This works without any issue. The problem is when there is a single quote (') in the filename to be compressed, e.g., B'b.txt. So, the command becomes

sh -c '7z a Aa.zip B'b.txt'

which does not run in the terminal.

These are the commands that I tried without any luck:

sh -c '7z a Aa.zip B'b.txt'
sh -c '7z a Aa.zip B\'b.txt'
sh -c '7z a Aa.zip B'"'"'b.txt'
sh -c '7z a Aa.zip "B'b.txt"'
sh -c '7z a Aa.zip \"B\'b.txt\"'
sh -c '7z a Aa.zip \"B'b.txt\"'
sh -c '7z a Aa.zip B'\''b.txt'

Running these commands result in either this error:

Syntax error: Unterminated quoted string

or waiting for input

>

which I then cancel using Ctrl + C.

I also tried using a variable and then pass it to sh -c. Again without any luck:

cmd="'7z a Aa.zip B'b.txt'"
echo $cmd
'7z a Aa.zip B'b.txt'
sh -c $cmd
a: 1: a: Syntax error: Unterminated quoted string

What am I doing wrong?

I know this question might sound familiar and may be similar to other questions like How can I escape quotes in command arguments to sh -c? and many others. But none of the methods marked as answer to these question work for me. So, please bear with me.


Solution

  • You're looking for:

    sh -c '7z a Aa.zip "B'\''b.txt"'
    

    This: '\'' is an escaped ' as a part of the string. You need that for the sh command itself. Once you've started running the command, leaving the ' unmatched causes a problem, so you need to put it inside of a string.