Reputation: 15588
In a shell script (in .zshrc) I am trying to execute a command that is stored as a string in another variable. Various sources on the web say this is possible, but I'm not getting the behavior i expect. Maybe it's the ~
at the beginning of the command, or maybe it's the use of sudo
, I'm not sure. Any ideas? Thanks
function update_install()
{
# builds up a command as a string...
local install_cmd="$(make_install_command $@)"
# At this point the command as a string looks like: "sudo ~some_server/bin/do_install arg1 arg2"
print "----------------------------------------------------------------------------"
print "Will update install"
print "With command: ${install_cmd}"
print "----------------------------------------------------------------------------"
echo "trying backticks"
`${install_cmd}`
echo "Trying \$()"
$(${install_cmd})
echo "Trying \$="
$=install_cmd
}
Output:
Will update install
With command: sudo ~some_server/bin/do_install arg1 arg2
trying backticks
update_install:9: no such file or directory: sudo ~some_server/bin/do_install arg1 arg2
Trying $()
update_install:11: no such file or directory: sudo ~some_server/bin/do_install arg1 arg2
Trying $=
sudo ~some_server/bin/do_install arg1 arg2: command not found
Upvotes: 31
Views: 27756
Reputation: 22382
Previous answers are correct, what worked for me was the below command in zsh
totalin=$(eval echo testing |wc -l)
echo "Total: $totalin"
Upvotes: 2
Reputation: 23955
I believe you have two problems here - the first is that your install_cmd
is being interpreted as a single string, instead of a command (sudo
) with 3 arguments.
Your final attempt $=install_cmd
actually does solve that problem correctly (though I'd write it as ${=install_cmd}
instead), but then you hit your second problem: ~some_server/bin/do_install
is not a known command. This is because sudo
doesn't interpret the ~
like you intend, for safety reasons; it would need to evaluate its arguments using the shell (or do some special-casing for ~
, which is really none of sudo
's business), which opens up a whole can of worms that, understandably, sudo
does its best to avoid.
That's also why it worked to do eval ${install_cmd}
- because that's literally treating the whole string as a thing to be evaluated, possibly containing multiple commands (e.g. if install_cmd
contained echo foo; sudo rm -rf /
it would be happy to wipe your system).
You have to be the one to decide whether you want install_cmd
to allow full shell semantics, including variable interpolation, path expansion, multiple commands, etc. or whether it should just expand the words out and run them as a single command.
Upvotes: 0
Reputation: 183201
As explained in §3.1 "Why does $var
where var="foo bar"
not do what I expect?" of the Z-Shell FAQ, you can use the shwordsplit
shell option to tell zsh
that you want it to split variables up by spaces and treat them as multiple words. That same page also discusses alternatives that you might want to consider.
Upvotes: 12