bash函数或脚本以在多个目录中执行命令

时间:2019-04-01 18:21:18

标签: bash

我想拥有可以在dir1dir2的参数中执行命令的命令

测试

# 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'

更新

也尝试过

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 "$@"也不保留引号

1 个答案:

答案 0 :(得分:4)

删除eval -这会引起很多解析问题,在这种情况下,您不需要它:

my-exec () {
  (cd $HOME/dir1 && "$@")
  (cd $HOME/dir2 && "$@")
}

您也可能会遇到麻烦,因为gca是别名,并且它们具有一组与之相关的单独的解析奇数。改用一个函数。但是请确保删除别名定义,否则它将覆盖该函数:

unalias gca
gca() {
    git commit -v -a "$@"
}

如果您确实确实确实需要保留gca作为别名而不是函数(为什么?),则需要使用eval,但是为了避免混淆复杂的参数,您需要重新引用它们。幸运的是,您可以使用bash printf的{​​{1}} format指令为参数添加合适的引号/转义符:

%q

但是,实际上,您应该使用函数而不是别名。它们具有更简洁的语法和语义,并且(如我们在此处看到的)在别名不存在的地方工作。