Вам нужно использовать eval
для обработки $SSH_CMD
, как если бы оно было введено как команда.
eval "$SSH_CMD"
Единственная обработка, выполняемая после расширения переменной, - это разбиение по словам и глобализация файла. Он не обрабатывает ecap, каналы, перенаправления, разделители команд и т. Д. Поэтому, когда вы выполнили эту команду, она была эквивалентна выполнению:
ssh -o BatchMode=yes -o ConnectTimeout=3 root@46.101.7.220 '2>&1' '|' grep '"Host' key verification 'failed."'
Я процитировал части команды, которые содержат метасимволы оболочки, чтобы указать, что они не обрабатываются специально после расширения переменной.
Результатом этого является то, что команда "2> & 1 | grep ... will be sent to the remote host. This will execute the commands
2> & 1 and
grep ...` на сервере, а не на клиенте, причем конвейер выполняется на а также сервер.
Для более простого примера попробуйте следующее:
data="foo | wc"
echo $data
Это напечатает foo | wc
буквально, не выполнит echo foo
и затем перенаправит его на wc
. Но если вы сделаете:
eval "echo $data"
будет действовать так, как если бы вы написали
echo foo | wc
Подробнее см. В разделе Работа с оболочкой в Руководстве по Bash. Обработка метасимволов, таких как |
и >
, выполняется на этом шаге:
- Разбирает токены на простые и составные команды (см. Команды оболочки ).
Расширение переменных выполняется на следующем шаге:
- Выполняет различные расширения оболочки (см. Расширения оболочки ), разбивая развернутые токены на списки имен файлов (см. Расширение имени файла ), а также команды и аргументы.
Поскольку расширение переменной происходит после поиска каналов и перенаправления, эти действия не будут выполняться локально, они будут выполняться в удаленной системе, когда команда отправляется ssh
.