How can I escape an arbitrary string for use as a command line argument in Bash?

后端 未结 8 1713
时光说笑
时光说笑 2020-12-08 13:44

I have a list of strings and I want to pass those strings as arguments in a single Bash command line call. For simple alphanumeric strings it suffices to just pass them verb

相关标签:
8条回答
  • 2020-12-08 14:04
    sub text_to_shell_lit(_) {
       return $_[0] if $_[0] =~ /^[a-zA-Z0-9_\-]+\z/;
       my $s = $_[0];
       $s =~ s/'/'\\''/g;
       return "'$s'";
    }
    

    See this earlier post for an example.

    0 讨论(0)
  • 2020-12-08 14:08

    You can use single quotes to escape strings for Bash. Note however this does not expand variables within quotes as double quotes do. In your example, the following should work:

    script.pl '!foo'
    

    From Perl, this depends on the function you are using to spawn the external process. For example, if you use the system function, you can pass arguments as parameters so there"s no need to escape them. Of course you"d still need to escape quotes for Perl:

    system("/usr/bin/rm", "-fr", "/tmp/CGI_test", "/var/tmp/CGI");
    
    0 讨论(0)
  • 2020-12-08 14:13

    If you want to securely quote anything for Bash, you can use its built-in printf %q formatting:

    cat strings.txt:

    yes
    no
    Hello, world
    C:\Program Files\
    "
    \
    \\
    \\\
    \\\\
    \\\\\
    "\
    "\T
    "\\T
    !1
    !A
    "!\/'"
    "Jeff's!"
    $PATH
    %PATH%
    &
    <>|&^
    *@$$A$@#?-_
    

    cat quote.sh:

    #!/bin/bash
    while IFS= read -r -d $'\n'
    do
        printf %q "$REPLY"
        printf '\n'
    done < strings.txt
    

    ./quote.sh:

    yes
    no
    Hello\,\ world
    C:\\Program\ Files\\
    \"
    \\
    \\\\
    \\\\\\
    \\\\\\\\
    \\\\\\\\\\
    \"\\
    \"\\T
    \"\\\\T
    \!1
    \!A
    \"\!\\/\'\"
    \"Jeff\'s\!\"
    \$PATH
    %PATH%
    \&
    \<\>\|\&\^
    \*@\$\$A\$@#\?-_
    

    These strings can be copied verbatim to for example echo to output the original strings in strings.txt.

    0 讨论(0)
  • 2020-12-08 14:13

    This is not a complete answer, but I find it useful sometimes to combine two types of quote for a single string by concatenating them, for example echo "$HOME"'/foo!?.*' .

    0 讨论(0)
  • 2020-12-08 14:17

    What is the general procedure for safely escaping an arbitrary string for use as a command line argument in Bash?

    Replace every occurrence of ' with '\'', then put ' at the beginning and end.

    Every character except for a single quote can be used verbatim in a single-quote-delimited string. There's no way to put a single quote inside a single-quote-delimited string, but that's easy enough to work around: end the string ('), then add a single quote by using a backslash to escape it (\'), then begin a new string (').

    As far as I know, this will always work, with no exceptions.

    0 讨论(0)
  • 2020-12-08 14:21

    FWIW, I wrote this function that invokes a set of arguments using different credentials. The su command required serializing all the arguments, which required escaping them all, which I did with the printf idiom suggested above.

    $ escape_args_then_call_as myname whoami

    escape_args_then_call_as() {
        local user=$1
        shift
    
        local -a args
        for i in "$@"; do
            args+=( $(printf %q "${i}") )
        done
    
        sudo su "${user}" -c "${args[*]}"
    }
    
    0 讨论(0)
提交回复
热议问题