0

I would like to execute a command which is given by a variable (Variable cmd in this example):

cmd="echo 'First argument'"
$cmd

Expected result would be:

First argument

BUT ... actual result is:

'First argument'

What? I don't understand why I can see single quotes in the output. After all, if the command (=content of variable $cmd) would be issued directly, then no quotes leak into the output, it behaves as desired:

$ echo 'First argument'
First argument

To illustrate what I am trying to achieve in real life: in my deploy script there is a code block like this (strongly simplified, but you get the point):

#!/bin/bash
function execute {
    cmd=$1
    echo "Executing $cmd ..."

    # execute the command:
    $cmd
}    

VERSION=1.0.2
execute "git tag -a 'release-$VERSION'"

Now, Git would create a tag which contains single quotes:

git tag
'1.0.2'

which is not what I want ...

What to do?

(Bash version: GNU bash 3.1.0)

(I found a very similar issue, here, but the answer would not apply to my problem)

2 Answers 2

3
cmd="echo 'First argument'"
$cmd

What happens there is word splitting and the actual resulting command is:

echo "'First" "argument'"

Double-parsing with the single quotes inside would never happen.

Also, it's better to use arrays:

#!/bin/bash

function execute {
    cmd=("$@")  ## $@ is already similar to an array and storing it to another is just optional.
    echo "Executing ${cmd[*]} ..."

    # execute the command:
    "${cmd[@]}"
}    

VERSION=1.0.2
execute git tag -a "release-$VERSION"

For eval is a difficult choice in that kind of situation. You may not only get unexpected parsing results, but also unexpectedly run dangerous commands.

Sign up to request clarification or add additional context in comments.

1 Comment

Marvellous! Great explanation and very clean code - I adopted your solution, it works perfectly.
1

I think this is what you want:

cmd="echo 'First arg'"
eval $cmd
First arg

1 Comment

Yep. Works, thanks. However, I prefer to avoid eval, that's why I chose konsolebox' solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.