Reputation: 85975
What function should I use to escape strings for shell command argument in C?
I have a string:
This is a string with () characters
This will be error:
echo This is a string with () characters
These are OK:
echo "This is a string with () characters"
echo This is a string with \(\) characters
Is there a predefined function convert #2 to #3 in C?
Upvotes: 11
Views: 6837
Reputation: 3097
C is not my language of choice, but here's what I came up with (having to answer the same question, myself).
#include <stdio.h> // sprintf
#include <stdlib.h> // malloc
#include <string.h> // strlen
char* escapeshellarg(char* str) {
char *escStr;
int i,
count = strlen(str),
ptr_size = count+3;
escStr = (char *) calloc(ptr_size, sizeof(char));
if (escStr == NULL) {
return NULL;
}
sprintf(escStr, "'");
for(i=0; i<count; i++) {
if (str[i] == '\'') {
ptr_size += 3;
escStr = (char *) realloc(escStr,ptr_size * sizeof(char));
if (escStr == NULL) {
return NULL;
}
sprintf(escStr, "%s'\\''", escStr);
} else {
sprintf(escStr, "%s%c", escStr, str[i]);
}
}
sprintf(escStr, "%s%c", escStr, '\'');
return escStr;
}
Given escape'this'
, it will output 'escape'\''this'\'''
, which can then be passed to echo
.
$ echo 'escape'\''this'\'''
escape'this'
Upvotes: 2
Reputation: 15827
Replace every single quote '
with '\''
then enclose the resulting string between single quotes '
:
char *escapeShellArg( char *arg )
{
char *esc;
uint16_t i,
j,
n;
n = strlen( arg );
esc = calloc( 1, n * 4 + 3 );
esc[0] = '\'';
j = 1;
for( i = 0; i < n; i++ )
{
if( arg[ i ] == '\'' )
{
esc[ j ] = '\'';
esc[ j+1 ] = '\\';
esc[ j+2 ] = '\'';
esc[ j+3 ] = '\'';
j += 4;
}
else
{
esc[ j++ ] = arg[ i ];
}
}
esc[ j ] = '\'';
return esc;
}
Upvotes: 1
Reputation: 215193
Replacing all instances of '
with '\''
then enclosing the whole string in single quotes ('
) is one safe way. This works even with embedded newlines. Another method would be to insert \
before each character, except that then you have to do some special treatment for newlines since \
followed by a newline is ignored by the shell, not treated as a literal newline. You'd have to surround newlines with '
(single quotes).
Upvotes: 10
Reputation: 94299
There is no predefined function.
However, I believe it's sufficient to just enclose any shell argument in single quotes, and making sure that single quotes are escaped.
That's the logic of the escapeshellarg function in PHP and I believe it works reasonably well.
Upvotes: 3
Reputation: 17016
Nothing pre-defined, and which characters need escaping depends on your shell. Look at the docs for your shell, and replace each X with \X. Using double quotes " will require the same treatment if the string you're enclosing contains a ".
Also note that this will get more complicated if you intend to encapsulate more complicated expressions (anything compounded with a ';', for example)
Upvotes: 1