docker -машина s sh пытается выполнить часть команды на локальной машине - PullRequest
1 голос
/ 18 марта 2020

При выполнении следующей команды:

docker-machine ssh name-here "docker swarm init --advertise-addr $(hostname -I | awk '{print $1}')"

я получаю следующую ошибку:

имя хоста: недопустимая опция - я использую: имя хоста [-fs] [имя- of-host]

Это потому, что команда пытается запустить hostname -I на моей локальной машине, работающей в MacOS, у которой нет флага -I.

Попытка запустить без двойных кавычек приводит к той же ошибке.

Я инкапсулировал полную команду в двойных кавычках, поэтому я ожидал, что все содержимое двойных кавычек будет выполнено как одиночные аргумент docker-machine ssh, но, похоже, дело не в этом.

Я пробовал одинарные кавычки ('), но это противоречит требованию единой кавычки awk в отношении печати. Я даже попробовал сумасшедший $$, как вы использовали бы в make-файлах рядом с именем хоста, но это тоже не работает.

Почему $(hostname -I | awk '{print $1}') выполняется на хост-машине, когда команда инкапсулирована в двойном формате? кавычки, и как я могу правильно выполнить вышеуказанную команду для инициализации роя docker с именем хоста в машине?

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

Согласно man bash:

Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $, , \, and, when history expansion is enabled, !. The characters $ and сохраняет свое специальное значение в двойных кавычках , Backsla sh сохраняет свое специальное значение только тогда, когда за ним следует один из следующих символов: $, `,", \ или. Двойная кавычка может заключаться в двойные кавычки, если перед ней стоит обратная косая черта sh. Если включено , расширение истории будет выполняться, если знак!, появляющийся в двойных кавычках, не будет экранирован с помощью обратного слэ sh. Обратный интервал sh, предшествующий символу!, не будет удален.

Так что с учетом этого следующие работы:

docker-machine ssh name-here 'docker swarm init --advertise-addr $(hostname -I | awk '\'{print \$1}\'')'

Обратите внимание, что $1 в печати экранируется с помощью \, и один набор одинарных кавычек также экранируется вокруг печати. ​​

1 голос
/ 18 марта 2020

Подстановки команд в двойных кавычках всегда выполняются «немедленно», то есть как часть Bash расширения команды. То, что вам нужно сделать, чтобы заключить подстановку команд, это использовать одинарные кавычки. Сравните двойные кавычки (локальная подстановка):

$ bash --noprofile --norc -o xtrace
bash-4.4$ ssh 127.0.0.1 "echo ${SSH_CONNECTION-No SSH connection}"
+ ssh 127.0.0.1 'echo No SSH connection'
No SSH connection

И одинарные кавычки (удаленная подстановка):

bash-4.4$ ssh 127.0.0.1 'echo ${SSH_CONNECTION-No SSH connection}'
+ ssh 127.0.0.1 'echo ${SSH_CONNECTION-No SSH connection}'
127.0.0.1 59618 127.0.0.1 22
...