Я видел вопросы и ответы о необходимости двойного экранирования аргументов для удаленных команд ssh. Мой вопрос: где и когда будет выполнен второй разбор?
Если я запускаю следующее:
$ ssh otherhost pstree -a -p
Я вижу следующее в выводе:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
Родительский процесс для удаленной команды ( pstree
) состоит в том sshd
, что там, похоже, нет никакой оболочки, которая бы анализировала аргументы командной строки для удаленной команды, поэтому не похоже, что двойные кавычки или экранирование будут необходимы ( но это точно так и есть). Если вместо этого я сначала ssh там и получаю оболочку входа в систему, а затем запускаю, pstree -a -p
я вижу следующее в выводе:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Ясно, что есть bash
оболочка, которая в этом случае будет выполнять синтаксический анализ командной строки. Но в случае, когда я использую удаленную команду напрямую, оболочки, похоже, не существует, так почему же нужна двойная кавычка?
Я думаю, я понял это:
Аргументы to
pstree
должны: показать аргументы командной строки, показать pids и показать только родительские процессы данного pid. Это'$$'
специальная переменная оболочки, которую bash заменит своим собственным pid, когда bash оценивает аргументы командной строки. Он цитируется один раз, чтобы не допустить его интерпретации моей локальной оболочкой. Но он не заключен в двойные кавычки или не экранирован, чтобы его можно было интерпретировать удаленной оболочкой.Как мы видим, он заменен на
12001
так, что это pid оболочки. Мы также можем видеть из вывода:pstree,12001
что процесс с pid 12001 - это сам pstree. Такpstree
это оболочка?Я собираюсь
bash
сказать, что он вызывается и анализирует аргументы командной строки, но затем вызываетexec
замену на выполняемую команду.Кажется, что это происходит только в случае одной удаленной команды:
В этом случае я запрашиваю две команды:
pstree
следуютecho
. И мы можем видеть здесь, чтоbash
на самом деле обнаруживается в дереве процессов в качестве родителяpstree
.источник
Поддерживая то, что сказали другие ответы, я посмотрел код, который вызывает команды на пульте, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...
... который, как вы можете видеть, безусловно вызывает
shell
первый аргумент-c
и второй аргументcommand
. Ранееshell
переменная была установлена в оболочку входа пользователя, как записано в/etc/passwd
.command
является аргументом этой функции, и в конечном итоге устанавливается для строки, дословно считываемой с провода (см.session_exec_req
тот же файл ). Таким образом, сервер вообще не интерпретирует команду, но на удаленном всегда вызывается оболочка.Тем не менее, соответствующая часть спецификации протокола SSH это не по всей видимости, требует такого поведения; это только говорит
Вероятно, это связано с тем, что не во всех операционных системах есть концепция оболочки командной строки. Например, для ssh-сервера Classic MacOS было бы сумасшествием передавать вместо этого строки команд exec интерпретатору AppleScript .
источник