eonil
eonil

Reputation: 85975

C function to escape string for shell command argument?

What function should I use to escape strings for shell command argument in C?

  1. I have a string:

    This is a string with () characters

  2. This will be error:

    echo This is a string with () characters

  3. 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

Answers (5)

nshew13
nshew13

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

Paolo
Paolo

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

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

Frerich Raabe
Frerich Raabe

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

jkerian
jkerian

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

Related Questions