Assigning command to a variable in Zsh

Viewed 627

I recently switched over to Zsh, and I have some configuration shell files I want to load into Zsh. However, it doesn't appear Zsh allows for command assignment by string to a variable.

What used to work

local git_conf='git config --global'
$git_conf rebase.autosquash true

In Bash the above works fine. However in Zsh it prints out:

command not found: git config --global

If I simply write the whole command out in the same file it works, but if I assign a partial command to a variable it doesn't. Is there a way around this?

Thanks,

3 Answers

Your want the shell to split your "command" on the spaces. Hence you have to invoke it as

${(z)git_conf} rebase.autosquash true

Of course this is a misuse of shell variables and works in such simple cases. I wonder why you do want to use a shell variable here, and not - say - a shell function. Even using an array variable would be more flexible.

This actually has already been answered. I asked a little early before my due diligence with the google. So I'll put in my answer below.

Solution

Using the eval function will work. But this is not best practice. For best practice I'm using a shell function.

In my case I have a lot of duplicate configurations that shorthands some of the typing so it's not as verbose. In this case I've further opted for an associative array of configurations considering each configuration will have a unique key.

declare -A confs
confs=(
    rebase.autosquash true
    alias.a '!ga() {
        if [ $# -eq 0 ]; then
            git add .
        else
            git add "$@"
        fi
    }; ga'
)

for key value in ${(kv)confs}
do
  # this works, however I'd like to stay away from eval whenever possible
  # command="specific command that's always the same ${key} ${value}"
  # eval ${command}

  # best practice
  git_config ${key} ${value}
done

git_config() {
    git config --global "$@"
}

You can also do:

local git_conf=(git config --global)
"$git_conf[@]" rebase.autosquash true
Related