0

I need to run a command with bash -c within a tmux session, from within a shell script. In contrast to screen, tmux seems to require to quote the entire command, which leads to problems as bash -c also requires quoting for correct functioning with more complex command strings.

In the following I'm trying to demonstrate the behavior with a minimal example. What I'm trying to achieve involves more complex commands than ls of course. Also for my purpose it is necessary to expand the CMD variable, as it is built in the script before.

A minimal script for screen:

#!/bin/bash

set -x

CMD="ls -l; sleep 5"

screen -d -m bash -c "$CMD"

When executing this script you get (stdout due to -x)

+ CMD='ls -l; sleep 5'
+ screen -d -m bash -c 'ls -l; sleep 5'

The sleep command is for having time to attach to the screen session and see what happens. When attaching to the screen session after executing the above script one sees that the output of the ls command is in long list format, i.e. the command is executed properly.

In tmux it seems one has to quote the command to get it executed in the new session. I use the following script:

#!/bin/bash

set -x

CMD="ls -l; sleep 5"

tmux new -d "bash -c $CMD"

The stdout is

+ CMD='ls -l; sleep 5'
+ tmux new -d 'bash -c ls -l; sleep 5'

As one can see, the cmd sequence for bash -c is not quoted properly anymore. When attaching to the created tmux session one can see, that this results in ls being executed without the long list option recognized.

What can I do to get the proper quoting (i.e. single quotes around the expanded string) for the $CMD string passed to bash -c?

Update

Escaping, as Eric Renouf suggested, with \"$CMD\" produces

tmux new -d 'bash -c "ls -l; sleep 5"'

and escaping with '$CMD' produces

tmux new -d 'bash -c '\''ls -l; sleep 5'\'''

Both works for the provided minimal example, but is still not exactly what screen produces and does not work in my case.

Here are the exact call I'm making (see here for all the gory details):

$SCREEN -S "scalaris_$NODE_NAME" -d -m bash -x -f +B -c "$START_CMD; sleep 365d"

which produces (output of -x)

/usr/bin/screen -S scalaris_first@pvs-pc07.zib.de -d -m bash -x -f +B -c '"/usr/bin/erl" -setcookie "chocolate chip cookie" -pa /home/jvf/code/scalaris/contrib/yaws/ebin -pa /home/jvf/code/scalaris/contrib/log4erl/ebin -pa /home/jvf/code/scalaris/ebin   -sasl sasl_error_logger false -yaws embedded true -scalaris log_path "\"/home/jvf/code/scalaris/log/first@pvs-pc07.zib.de\"" -scalaris docroot "\"/home/jvf/code/scalaris/docroot\"" -scalaris config "\"/home/jvf/code/scalaris/bin/scalaris.cfg\"" -scalaris local_config "\"/home/jvf/code/scalaris/bin/scalaris.local.cfg\"" -connect_all false -hidden -name first@pvs-pc07.zib.de   -scalaris start_type first -scalaris port 14195 -scalaris yaws_port 8000 -scalaris join_at_list '\''[0]'\'' -scalaris start_mgmt_server true -scalaris nodes_per_vm "1" -s scalaris +sbt db +swt low +sbwt short'

I think the solutions suggested so far do not work because of the use of double quotes within the command, but I'm not 100% positive about that. How can I reproduce the exact quoting screen produces (single quotes around the complete command passed to bash -c) with tmux?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
jvf
  • 866
  • 7
  • 13
  • You may want to read up [here](http://mywiki.wooledge.org/BashFAQ/050) for some of the difficulties with this, though I'm wouldn't have predicted in advance that `tmux` would have more trouble than `screen` – Eric Renouf Aug 27 '15 at 13:51

1 Answers1

0

I'm trusting that you need to do this for tmux, but to get the extra quotes you want, you could just escape them in the outer quote like:

tmux new -d "bash -c \"$CMD\""

or you could put those in single quotes in most cases like

tmux new -d "bash -c '$CMD'"

since the $CMD will be expanded by the outer quotes

Eric Renouf
  • 13,950
  • 3
  • 45
  • 67
  • This works for the minimal example I provided above, but does not produce exactly the same quoting and unfortunately doesn't work for what I'm trying to achieve... – jvf Aug 27 '15 at 13:40