How to store a command in a variable in a shell script?

前端 未结 8 994
长情又很酷
长情又很酷 2020-11-22 07:35

I would like to store a command to use at a later period in a variable (not the output of the command, but the command itself)

I have a simple script as follows:

相关标签:
8条回答
  • 2020-11-22 08:27

    Do not use eval! It has a major risk of introducing arbitrary code execution.

    BashFAQ-50 - I'm trying to put a command in a variable, but the complex cases always fail.

    Put it in an array and expand all the words with double-quotes "${arr[@]}" to not let the IFS split the words due to Word Splitting.

    cmdArgs=()
    cmdArgs=('date' '+%H:%M:%S')
    

    and see the contents of the array inside. The declare -p allows you see the contents of the array inside with each command parameter in separate indices. If one such argument contains spaces, quoting inside while adding to the array will prevent it from getting split due to Word-Splitting.

    declare -p cmdArgs
    declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'
    

    and execute the commands as

    "${cmdArgs[@]}"
    23:15:18
    

    (or) altogether use a bash function to run the command,

    cmd() {
       date '+%H:%M:%S'
    }
    

    and call the function as just

    cmd
    

    POSIX sh has no arrays, so the closest you can come is to build up a list of elements in the positional parameters. Here's a POSIX sh way to run a mail program

    # POSIX sh
    # Usage: sendto subject address [address ...]
    sendto() {
        subject=$1
        shift
        first=1
        for addr; do
            if [ "$first" = 1 ]; then set --; first=0; fi
            set -- "$@" --recipient="$addr"
        done
        if [ "$first" = 1 ]; then
            echo "usage: sendto subject address [address ...]"
            return 1
        fi
        MailTool --subject="$subject" "$@"
    }
    

    Note that this approach can only handle simple commands with no redirections. It can't handle redirections, pipelines, for/while loops, if statements, etc

    Another common use case is when running curl with multiple header fields and payload. You can always define args like below and invoke curl on the expanded array content

    curlArgs=('-H' "keyheader: value" '-H' "2ndkeyheader: 2ndvalue")
    curl "${curlArgs[@]}"
    

    Another example,

    payload='{}'
    hostURL='http://google.com'
    authToken='someToken'
    authHeader='Authorization:Bearer "'"$authToken"'"'
    

    now that variables are defined, use an array to store your command args

    curlCMD=(-X POST "$hostURL" --data "$payload" -H "Content-Type:application/json" -H "$authHeader")
    

    and now do a proper quoted expansion

    curl "${curlCMD[@]}"
    
    0 讨论(0)
  • 2020-11-22 08:28

    For bash, store your command like this:

    command="ls | grep -c '^'"
    

    Run your command like this:

    echo $command | bash
    
    0 讨论(0)
提交回复
热议问题