コンテキスト: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
コマンドを使用できません(または、少なくともそれを機能させることに成功しませんでした)。
最初の出力行を端末で直接実行すると、問題なく動作します。
どうすればこの問題を克服できますか?
これは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