Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escape ampersand in bash

Tags:

bash

I have the following code:

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

My problem is that what I got is as result is:

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

I mean for some strange reason the double ampersand is escaped. How could I solve the issue?

like image 388
Mazzy Avatar asked Feb 11 '26 17:02

Mazzy


1 Answers

The && isn't really being escaped; it's just that it has no special meaning inside a simple command.

When you write something like this:

foo && bar

Bash interprets that as two separate simple commands — foo and bar — joined by the control operator &&.

But when you write something like this:

cmd='foo && bar'
$cmd

you only have one simple command, $cmd. Bash performs parameter-substitution (replacing $cmd with foo && bar) and word-splitting (replacing foo && bar with foo && bar), but it doesn't search for any special characters like && or > or | or '.


To fix this, you'll need to use a different approach. In your example, you're best off just eliminating the extra indirection:

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

but in a more complicated example, you might find it helpful to write a helper function.

like image 178
ruakh Avatar answered Feb 15 '26 02:02

ruakh