我希望有一个命令可以在dir1
和dir2
中的参数中执行命令
测试
# put this in our .bashrc
alias gca="git commit -v -a"
my-exec gca
my-exec gca -m "my commit wrapped in double quotes"
my-exec gca -m "my commit wrapped in double quotes with 'something' in single quotes"
my-exec gca -m 'my commit wrapped in single quotes with "something" in double quotes'
我试过了
my-exec () {
(cd $HOME/dir1 && eval "$@")
(cd $HOME/dir2 && eval "$@")
}
但它不起作用,因为
# working fine
my-exec gca
# executes
# gca -m my commit wrapped in double quotes
# actually
my-exec gca -m "my commit wrapped in double quotes"
# didnt try
my-exec gca -m "my commit wrapped in double quotes with 'something' in single quotes"
# didnt try
my-exec gca -m 'my commit wrapped in single quotes with "something" in double quotes'
UPDATE
也试过了
my-exec () {
echo "$@" > /tmp/my-exec
cat /tmp/my-exec
(cd $HOME/dir1 && bash -i /tmp/my-exec)
(cd $HOME/dir2 && bash -i /tmp/my-exec)
}
但echo "$@"
也不保留报价
删除eval
- 它会导致许多解析问题,在这种情况下你不应该需要它:
my-exec () {
(cd $HOME/dir1 && "$@")
(cd $HOME/dir2 && "$@")
}
你可能也会遇到麻烦,因为gca
是一个别名,他们有一组独立的解析奇怪的东西。请改用功能。但一定要删除别名定义,否则它将覆盖该函数:
unalias gca
gca() {
git commit -v -a "$@"
}
如果你真的真的需要保持gca
作为别名而不是函数(为什么?),你需要使用eval
,但为了避免搞砸复杂的参数,你需要重新引用它们。幸运的是,您可以使用bash printf
的%q
格式指令为参数添加合适的引用/转义:
my-exec () {
(cd $HOME/dir1 && "$(printf '%q ' "$@")")
(cd $HOME/dir2 && "$(printf '%q ' "$@")")
}
但实际上,您应该使用函数而不是别名。它们具有更清晰的语法和语义,并且(正如我们在这里看到的)在别名没有的地方工作。