Основная проблема в том, что команда отправляется через ssh
;это означает, что он выполняет два уровня разбора оболочки: один на локальном компьютере, а другой на удаленном компьютере.Это означает, что он дважды выполняет синтаксический анализ, применение и удаление кавычек, поэтому вам нужно два «слоя» цитирования / экранирования.
Команда в последнем комментарии не разбирает (несовпадающие кавычки), ноЯ могу воспроизвести сообщение об ошибке с помощью этой команды:
ssh remoteHost "sudo sed -i "s/batch_start.*/batch_start\ 1111/" /tmp/runfile"
Этот тип имеет два уровня кавычек, но кавычки не вкладываются, поэтому он не работает.Локальная оболочка анализирует это как строку в двойных кавычках "sudo sed -i "
, затем секцию без кавычек s/batch_start.*/batch_start\ 1111/
(которая содержит пробел, так что он удалит escape), а затем еще одну секцию в двойных кавычках: " /tmp/runfile"
.Поскольку между ними нет пробелов, все они передаются ssh
как один аргумент.Вы можете увидеть строку после разбора, заменив ssh remoteHost
на echo
:
$ echo "sudo sed -i "s/batch_start.*/batch_start\ 1111/" /tmp/runfile"
sudo sed -i s/batch_start.*/batch_start 1111/ /tmp/runfile
... так что это команда, которую выполнит удаленная оболочка.Поскольку между s/batch_start.*/batch_start
и 1111/
есть пробел, они передаются в sed
как отдельные аргументы, и первая обрабатывается как команда для выполнения (в которой отсутствует закрывающая /
), а вторая - как имя файла.
Решение: существует много способов исправить цитату.Вы можете использовать трюк echo
, чтобы увидеть, что будет отправлено на удаленную оболочку.Я предпочитаю отдавать одинарные кавычки вокруг всей команды, а затем просто заключать в них обычные кавычки (если внутренняя команда сама не содержит одинарных кавычек).В этом случае это означает:
ssh remoteHost 'sudo sed -i "s/batch_start.*/batch_start 1111/" /tmp/runfile'
, который выполняет это на удаленном компьютере:
sudo sed -i "s/batch_start.*/batch_start 1111/" /tmp/runfile
(обратите внимание, что я удалил escape на месте.)