【问题标题】:Executing 'bash -c' in 'docker exec' command在“docker exec”命令中执行“bash -c”
【发布时间】:2018-10-17 06:33:51
【问题描述】:

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

我读到here,您可以通过在启动 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

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

如果我直接在终端中执行第一行输出,它就可以正常工作。

我该如何克服这个问题?

【问题讨论】:

  • 一些技巧可以在mywiki.wooledge.org/BashFAQ/050找到
  • @EricRenouf 谢谢!我已经在我的研究中偶然发现了这一点,但似乎找不到适用于我的案例的段落......你看到合适的段落了吗? (可能是第三部分,但我不太明白)
  • 您是否考虑过将参数存储在数组而不是字符串中的初始部分?此外,COLUMNSLINES 是否可能包含意外的换行符或类似的东西?也许那些也应该被引用?
  • 我尝试用硬编码值替换 COLUMNSLINES 但没有帮助。你会把哪一部分写成数组?如果我接受命令并直接在终端中执行它,它就可以工作,这就是我没有得到的

标签: bash docker docker-exec


【解决方案1】:

这与 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 是一个动态变量,它以第二个命令行参数为值
  • 因为$cmd$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

【讨论】:

  • 我想我明白了。但仍有一些问题困扰着我:使用此解决方案,我必须对变量进行硬编码:在我的情况下为 foo='winpty docker exec -it 0b63a bash -c "stty cols 255 rows 59 && bash -l"'。你知道在命令中使用变量的好方法吗?我可以一个接一个地评估它们,然后粘上整个东西,但感觉不对
  • 是的,让我修正一下答案
猜你喜欢
  • 2015-06-07
  • 2017-06-19
  • 2017-07-10
  • 2020-09-08
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 2017-09-16
  • 2021-07-11
相关资源
最近更新 更多