Как передать $@ bash через ssh, учитывая пробелы в аргументах?
Я хочу удобно читать журналы со своего сервера. Я пытаюсь написать сценарий, который считывает выходные данные с моего сервера, применяя параметры, которые я передаю, к сценарию для вызова. Возможно, я захочу применить различные фильтры, поэтому мне нужно, чтобы аргументы моего сценария преобразовывались вjournalctl
аргументы. Например
побежал бы
ssh host journalctl --since '2 days ago'
Я попробовал это:
#/usr/bin/env bash
ssh host journalctl "$@"
Но когда я звоню
bin/log --since '2 days ago'
Я просто говорю:
Failed to parse timestamp: 2
Хорошо, мы получили аргумент с пробелами, который, похоже, преобразуется в несколько аргументов при передаче как часть команды по SSH. Затем я попробовал что-то вроде этого:
#/usr/bin/env bash
ssh host bash -c 'journalctl autotests "$@"'
Вы можете догадаться, что это не делает то, что мне нужно.
Как, черт возьми, мне пройти$@
через SSH?
1 ответ
Этот вопрос: как выполнить сложную командную строку через ssh, в некоторой степени связан. Мой ответ сосредоточен на случае, когда локально ничего не расширяется; ты хочешь расширить$@
локально это усложняет ситуацию. Тем не менее связанный ресурс может дать вам некоторое представление о том, как все это работает.
В вашем случае самый простой способ - использоватьQ
оператор (см. начало другого моего ответа ):
#!/usr/bin/env bash
ssh host "journalctl autotests ${@@Q}"
Приведенный выше код не будет работать в чистом виде
sh
, вам нужно (местный)
bash
. "Шебанг" в вашем вопросе
#/usr/bin/env bash
, это не чушь, это просто комментарий; Шебанг должен начинаться с
#!
. В приведенном выше коде используется правильный шебанг.
Обратите внимание, если вы это сделаете:
ssh host bash -c "journalctl autotests ${@@Q}"
тогда в шелл-коде на удаленной стороне не будет одного уровня кавычек. Если вам действительно нужно, то вы можете сделать следующее:
#!/usr/bin/env bash
cmd="journalctl autotests ${@@Q}"
ssh host "bash -c ${cmd@Q}"
Дополнительное использование@Q
дает вам дополнительный уровень цитирования (или экранирования), который вам нужен. Но в данном конкретном случае вам, скорее всего, не понадобитсяbash -c
вообще, первая команда, которую я вам дал, должна сработать.