在bash中逃脱&符号

时间:2018-01-22 23:17:50

标签: bash

我有以下代码:

ANSIBLE_WORK_DIR=${ANSIBLE_WORK_DIR:-$(pwd)/ansible}

ansible_work_dir() {
  echo "${ANSIBLE_WORK_DIR}"
}

ansible_run() {
  local cmd
  ansible_dir=$(ansible_work_dir)

  cmd="cd $ansible_dir && ansible-playbook --extra-vars env=${ENV}"
  $cmd "${@}"
}

ansible_run playbooks/secrets/write.yml

我的问题是我得到的结果是:

cd /home/ubuntu/ansible '&&' ansible-playbook --extra-vars env=test playbooks/secrets/write.yml

我的意思是出于一些奇怪的原因,双&符号被逃脱了。我怎么能解决这个问题?

2 个答案:

答案 0 :(得分:3)

&&并未真正被转义;它只是在一个简单的命令中没有特殊意义。

当你写这样的东西时:

foo && bar

Bash将其解释为两个单独的简单命令 - foobar - 由控制运算符&&加入。

但是当你写这样的东西时:

cmd='foo && bar'
$cmd

您只有一个简单命令$cmd。 Bash执行参数替换(将$cmd替换为foo && bar)和分词(将foo && bar替换为foo && bar),但它不搜索任何特殊字符,例如&&>|'

要解决此问题,您需要使用其他方法。在你的例子中,你最好只是消除额外的间接性:

  cd "$ansible_dir" && ansible-playbook --extra-vars env="${ENV}" "${@}"

但是在一个更复杂的例子中,您可能会发现编写辅助函数很有帮助。

答案 1 :(得分:2)

cmd="cd $ansible_dir && ..."

你不能在变量中使用这样的命令,只有在解释了&&这样的特殊语法之后才会扩展变量。

但我无法理解你为什么要这样做,为什么不直接执行cd命令?

ansible_run() {
  ansible_dir=$(ansible_work_dir)
  cd $ansible_dir && ansible-playbook --extra-vars env="${ENV}" "$@"
}