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

问题描述 投票:0回答:1

我希望有一个命令可以在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'

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 "$@"也不保留报价

bash
1个回答
4
投票

删除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 ' "$@")")
}

但实际上,您应该使用函数而不是别名。它们具有更清晰的语法和语义,并且(正如我们在这里看到的)在别名没有的地方工作。

© www.soinside.com 2019 - 2024. All rights reserved.