web-dev-qa-db-ja.com

'dockerexec'コマンドで 'bash-c'を実行しています

コンテキスト: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コマンドを使用できません(または、少なくともそれを機能させることに成功しませんでした)。

最初の出力行を端末で直接実行すると、問題なく動作します。

どうすればこの問題を克服できますか?

6
AdrienW

これはDockerに関連していませんが、Bash(つまり、コマンドのdockerの部分はうまく機能し、ホストで不平を言うようにコンテナーで不平を言うだけです):

最小限の再現可能なエラー

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は、2番目のコマンドライン引数を値として受け取る動的変数です。
  • $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
6
Arount