9

上下文:我正在尝试为我日常使用该docker exec命令编写一个快捷方式。出于某些原因,我正在试验一个问题,即当我在容器内使用 bash 控制台时,我的输出有时会被破坏(历史混乱,行在我写作时相互覆盖,......)

我在这里读到,您可以通过在启动 bash 控制台之前添加一些命令来克服这个问题。


这是我的脚本所做的相关摘录

#!/bin/bash
containerHash=$1
commandToRun='bash -c "stty cols $COLUMNS rows $LINES && bash -l"'

finalCommand="winpty docker exec -it $containerHash $commandToRun"
echo $finalCommand
$finalCommand

这是我得到的输出:

winpty docker exec -it 0b63a bash -c "stty cols $COLUMNS rows $LINES && bash -l"
cols: -c: line 0: unexpected EOF while looking for matching `"'
cols: -c: line 1: syntax error: unexpected end of file

我在这里读到这与解析和扩展有关。但是,我不能使用函数或eval命令(或者至少我没有成功使它工作)。

如果我直接在终端中执行第一条输出行,它就可以毫无问题地工作。

我该如何克服这个问题?

4

1 回答 1

9

它与 Docker 无关,但与 Bash 无关(换句话说,命令中 docker 的部分运行良好,它只是 bash 对容器发牢骚,就像它在您的主机上发牢骚一样):

最小的可重现错误

cmd='bash -c "echo hello"'
$cmd

hello": -c: line 0: unexpected EOF while looking for matching `"'
hello": -c: line 1: syntax error: unexpected end of file

使固定

cmd='bash -c "echo hello"'
eval $cmd

hello

回答

foo='docker exec -it XXX bash -c "echo hello"'
eval $foo

这将使您可以echo hello在容器上执行命令,现在如果您想向该命令添加动态变量(例如echo $string),您只需去掉双引号的单引号,要使其正常工作,您必须转义内部双引号:

foo="docker exec -it $container bash -c \"echo $variable\""

一个完整的例子

FOO="Hello"
container=$1
bar=$2

cmd="bash -c \"echo $FOO, $bar\""
final_cmd="docker exec -it $container $cmd"

echo "running command: \"$final_cmd\""
eval $final_cmd

让我们花时间去挖掘,

  • $FOO是一个静态变量,在我们的例子中,它的工作方式与常规变量完全一样,只是为了向您展示。
  • $bar是一个动态变量,它以第二个命令行参数为值
  • 因为$cmdand$final_cmd只使用双引号,所以变量被解释
  • 因为我们使用eval $final_cmd命令得到很好的解释,所以 bash 很高兴。

最后,一个使用示例:

bash /tmp/dockerize.sh 5b02ab015730 world

running command: "docker exec -it 5b02ab015730 bash -c "echo Hello, world""
Hello, world
于 2018-05-07T13:17:31.833 回答