I have an expect script, and want to spawn a BASH command for it to provide input to. When I use the following syntax:

spawn /bin/bash docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki`


spawn docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

I get the following error:

bad flag "-it": must be -glob, -regexp, -exact, -notransfer, -nocase, -i, -
indices, -iread, -timestamp, -timeout, -nobrace, or --
    while executing
"expect {
   spawn (/bin/bash) docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn 
   "Enter PEM pass phrase:"   {send "DefPEMVPNPassPhra..."
    (file "addcontainer.exp" line 7)

How do I tell expect to spawn a BASH command?


3 Answers 3


The syntax to access environment variables in TCL (expect is a TCL interpreter) is $env(VARNAME), so:

spawn docker run -v $env(OVPN_DATA):/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

If you want to run a shell to interpret some shell code, you'd run sh -c the-code (or bash -c though there's nothing bash-specific in that shell code here). That's what the system() function of most languages to.

spawn sh -c {
  docker run -v "$OVPN_DATA:/etc/openvpn" --rm -it kylemanna/openvpn ovpn_initpki

{...} are the strong quotes in TCL. I also added the missing quotes around the shell variable expansion, as otherwise it would be more zsh/rc/fish syntax than sh syntax.

Also, you'd spawn before any expect ... statement. The spawn command is to launch the command you want to interact with, the expect ... statement is to wait for specific output from that command.

In your code above, you're not running spawn at all, that spawn inside the expect argument is take as a pattern to look for in the output of an earlier spawned command if any, or from stdin if not.


The output suggests that spawn doesn't stop interpreting flags when it encounters a command name.

A common convention is to use -- as a separator between options for a command (which it should parse and interpret), and arguments to things it needs to call (which it should ignore and pass on).

The spawn output lists -- as one of the possible options, which suggests that it follows that convention. Try specifying it?

spawn /bin/bash -- -c "docker run ..."
  • the -- probably shouldn't be placed after bash and before bash flags ...
    – thrig
    Feb 7, 2018 at 17:56


spawn /bin/bash
send "docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn  ovpn_initpki"
  • You will need to escape the $ as tcl will expand this within "". Or you can replace the double quotes by {} quotes.
    – meuh
    Feb 7, 2018 at 16:51
  • It's also possible that the quoting can be dropped, and just the -c will be enough to load up bash. Or maybe just quote "docker", though that may not take care of how tcl will handle the variable definitions within the expect file.
    – John
    Feb 7, 2018 at 16:53
  • bad flag "-c": must be -glob, -regexp, -exact, -notransfer, -nocase, -i, -indices, -iread, -timestamp, -timeout, -nobrace, or --
    – William
    Feb 7, 2018 at 17:20
  • The error that you are reporting is from expect. I updated my answer
    – John
    Feb 7, 2018 at 17:52
  • @JohnW.Gill Not sure what's going on. No errors when I use that code but the container shows many errors saying that the configuration files don't exist (that are created with that input). I'll investigate further.
    – William
    Feb 7, 2018 at 19:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .