Как правильно избежать двойных кавычек в команде ssh pkill bash?

$ ssh [email protected]
123.123.123.123# pkill -f "stalled process name"; commands_to_restart; some_more_commands;
many many lines of output demonstrating success
123.123.123.123# exit;

ВСЕ РАБОТАЕТ ОТЛИЧНО

$ ssh [email protected] "pkill -f "\""stalled process name"\"";"\
> "commands_to_restart; some_more_commands;";

нет вывода, НИЧЕГО НЕ ДЕЛАЕТ.

$ ssh [email protected] "echo "\""pkill -f "\"\\\"\""stalled process name"\"\\\"\""; "\
> "commands_to_restart; some_more_commands;"\"";";
pkill -f "stalled process name"; commands_to_restart; some_more_commands;

Итак... ДВА этапа экранирования цитаты работают, как и ожидалось...

Как заставить один слой цитаты работать с ssh/bash? Поскольку цитирование отлично работает в двух слоях, у меня такое ощущение, что оно имеет меньшее отношение к цитированию и больше к некоторым аспектам обработки терминала ssh. Тем не менее, насколько я знаю, команды не делают ничего, кроме простого и обычного ввода-вывода на стандартный вывод и без ввода.


person user3338098    schedule 09.05.2018    source источник
comment
Ничего общего с терминальной обработкой, как таковой. Нужно понимать, что ssh объединяет все свои аргументы в одну строку и отправляет эту строку по сети.   -  person Charles Duffy    schedule 09.05.2018
comment
Следовательно, синтаксические кавычки, попадающие в границы между этими аргументами, полностью отбрасываются — они используются вашей локальной оболочкой при формировании списка аргументов ssh, но затем ssh отбрасывает эту информацию: локально-синтаксические кавычки отбрасываются локальной оболочкой, и буквенные кавычки, передаваемые в списке аргументов, обрабатываются удаленной оболочкой как синтаксис.   -  person Charles Duffy    schedule 09.05.2018
comment
Это ошибка дизайна, но это ошибка дизайна, которую можно исправить только с помощью нового проводного протокола (который передает по сети несколько строк, а не только одну), поэтому шансы на то, что это будет исправлено в будущем... исчезающе вряд ли.   -  person Charles Duffy    schedule 09.05.2018
comment
@CharlesDuffy Оказывается, цитирование IS идеально! Провел часы, читая все о процессе экранирования кавычек оболочки / ssh, прежде чем понял, что проблема заключалась в том, что pkill был самореферентным для sh -c '... pkill -f "other process";...'процесса, запущенного ssh. ржунимагу   -  person user3338098    schedule 12.05.2018
comment
решение состоит в том, чтобы сделать ssh "pkill \"\`echo O\`ther process\"; other_commands;"   -  person user3338098    schedule 12.05.2018
comment
Тот факт, что вам нужно заключать в кавычки иначе, чем для локальной команды, несовершенен, и то, о чем я говорил выше, было бы ненужным, если бы SSH не был неправильно спроектирован.   -  person Charles Duffy    schedule 12.05.2018


Ответы (2)


Вам лучше использовать heredoc для таких вещей:

ssh [email protected] bash -s << 'EOF'
    pkill -f "stalled process name"
    commands_to_restart
    some_more_commands
EOF
  • bash -s гарантирует, что вы используете bash, а не пользовательскую оболочку на удаленном хосте
  • цитирование маркера конца heredoc ('EOF') гарантирует, что содержимое передается как есть, без его интерпретации родительской оболочкой.
person codeforester    schedule 09.05.2018
comment
принято, потому что это не приводит к тому, что bash -c pkill\040-f\040"stalled\040process\040name";commands_to_restart;some_more_commands; отображается в аргументах командной строки на сервере и не приводит к тому, что pkill убивает свою собственную среду оболочки, что было реальной проблемой, с которой я столкнулся. - person user3338098; 27.07.2018

Пытаться:

ssh [email protected] 'pkill -f "stalled process name"; commands_to_restart; some_more_commands'

С командой в одинарных кавычках нет необходимости избегать внутренних двойных кавычек.

Если вы предпочитаете использовать только двойные кавычки, то одинарное экранирование внутренних двойных кавычек должно быть удовлетворительным:

ssh [email protected] "pkill -f \"stalled process name\"; commands_to_restart; some_more_commands"
person John1024    schedule 09.05.2018
comment
не принято, потому что цитирование не было проблемой. Это приведет к тому, что ssh запустит bash -c pkill\040-f\040"stalled\040process\040name";commands_to_restart;some_more_commands;, и, таким образом, pkill уничтожит свою собственную оболочку и предотвратит выполнение commands_to_restart. - person user3338098; 27.07.2018