lerei
lerei

Reputation: 113

How to pass all bash arguments to bash -c within command substitution?

I am trying to conditionally pass script arguments to bash -c, which itself is passed to a docker run command. The example below illustrates what I am trying to do.

#!/bin/bash

echo "Args: ${@}"
docker run ubuntu \
  $( if [[ ! -z ${@} ]]; then echo "bash -c ${@}"; fi )

docker run ubuntu \
  $( if [[ ! -z ${@} ]]; then echo "bash -c \"${@}\""; fi )

For a call ./myscript.sh ls -la, this gives me the following output.

Args: ls -la
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
-la": -c: line 0: unexpected EOF while looking for matching `"'
-la": -c: line 1: syntax error: unexpected end of file

As you can see, the first docker run call works, but ignores the -la flag that has also been passed. I thought about trying to enclose the command passed to bash -c, namely ls -la, in escaped quotes, but this doesn't work at all.

How can I realize the desired behavior? Thanks in advance!

Upvotes: 0

Views: 837

Answers (1)

user1934428
user1934428

Reputation: 22291

You basically are doing a

bash -c ls -la

You can reproduce this, if you are doing the same command on the command line: It would give the same result.

From the bash man-page about the -c option:

... commands are read from the first non-option argument command_string. If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets the name of the shell, which is used in warning and error messages.

Therefore, the -la is not passed as argument to ls. You would have to do a

bash -c "ls -la"

If I understand your code correctly, you don't want run the arguments on docker, if the argument list is empty. I would then try a

(( $# > 0 )) && docker run ubuntu bash -c "$*"

Upvotes: 1

Related Questions