Почему 'CD' управляет не, работают через SSH?

Я пытался скопировать некоторые файлы через SSH, но вместо tar'луг те, которых я хотел, я получил свою домашнюю папку. Я сделал некоторое дальнейшее тестирование, и оно сводится к этому:

ssh root@server /bin/sh -c "cd /boot && ls -l"

Который к моему удивлению перечисляет файлы в /root нет /boot. Но если я выполняю все /bin/sh команда от терминала это правильно cds и печать /boot файлы.

Что происходит здесь?

41
21.04.2017, 01:24
4 ответа

ssh не позволяет Вам указать команду точно, поскольку Вы сделали как серия аргументов, которые будут переданы execvp на удаленном хосте. Вместо этого это связывает все аргументы в строку и выполняет их через удаленную оболочку. Это выделяется как главный недостаток дизайна в ssh, по-моему... это - инструмент Unix хорошего поведения большинством способов, но когда он прибывает время для определения команды, он принял решение использовать единственную монолитную строку вместо argv, как он был разработан для MS-DOS или чего-то!

Так как ssh передаст Вашу команду как единственную строку к sh -c, Вы не должны обеспечивать свое собственное sh -c. Когда Вы делаете, результат

sh -c '/bin/sh -c cd /boot && ls -l'

с исходным потерянным заключением в кавычки. Так команды, разделенные && :

`/bin/sh -c cd /boot`
`ls -l`

Первое из тех выполнений оболочка с текстом команды "CD" и $0="boot". Команда "CD" завершается успешно, $0 не важно, и /bin/sh -c указывает на успех, затем ls -l происходит.

36
27.01.2020, 19:35
  • 1
    В то время как я соглашаюсь, что это неудачно это ssh ведите себя как этот, если бы это не было, то это нужно было бы назвать sexec, нет ssh. ssh защищенная версия rsh (который вел себя то же в том отношении), и rlogin (rsh названный rlogin при отсутствии передачи командная строка). Просто неудачно, что это не реализует rexec также. –  Stéphane Chazelas 27.06.2013, 12:02
  • 2
    @StephaneChazelas был там когда-нибудь командой королей? Это - просто библиотечная функция C насколько я знаю. Положительная сторона, хотя, о rsh. Быть общедоступной заменой для rsh было ключом к быстрому принятию в первые годы ssh, когда у всех были тонны сценариев уже с помощью rsh. –   28.06.2013, 00:12
  • 3
    я определенно использовал его в прошлом. Смотря теперь, это, должно быть, было на HPUX как не, много других Нельдов, кажется, имеют его, я должен признать, хотя у меня создалось впечатление, это было более широко распространено. –  Stéphane Chazelas 28.06.2013, 00:27
  • 4
    Спасибо. Это действительно помогло, особенно так как я туннелирую с ssh. Я должен был сделать ssh-t machine1 'ssh-t machine2 "эхо \"1 && 2 \""' для получения '1 && 2' как вывода. Это уничтожило несколько часов. –  ghayes 17.08.2013, 01:00
  • 5
    AMD, Если Вы действительно хотите передать команду точно, например, от "$", можно использовать это: "`printf "%q " "$@"`" с ударом printf заключить в кавычки строку или строки с Escape оболочки. –  Sam Watkins 28.05.2016, 05:23

İt проблема заключения в кавычки. Ssh уже выполняет команду, Вы передаете его в оболочке. Когда Вы передаете несколько параметров, они связываются с пространством, промежуточным для создания строки. Таким образом, удаленная команда, которую Вы выполняете удаленно, /bin/sh -c cd /boot && ls -l (никакие кавычки, потому что кавычки в Вашей команде интерпретировались локальной оболочкой).

/bin/sh -c cd /boot выполнения /bin/sh и говорит этому выполнять команду cd и также установить $0 кому: /boot. После того как это сделано, родительская оболочка (тот, запущенный sshd) выполнения ls -l.

В Вашем случае просто удалите sh -c который абсолютно бесполезен если Ваша удаленная оболочка (как обозначено в /etc/passwd или другая база данных пароля), не понимает эту команду.

ssh root@server "cd /boot && ls -l"

Если необходимо вызвать другую оболочку, необходимо заключить удаленную команду в кавычки для защиты ее от расширения удаленной оболочкой, вызванной sshd. Например, если Ваша оболочка входа в систему является тире, и Вы хотите выполнить команду удара:

ssh root@server 'bash -c "cd ~bob && ls -l"'
36
27.01.2020, 19:35

Я думаю, что это имеет больше, чтобы сделать с тем, как опции становятся проанализированными оболочкой. Например, это работает:

$ ssh root@server /bin/sh -c '"cd /boot && ls -l"'

Это имеет ту же проблему как Ваша команда:

$ ssh root@server /bin/sh -c 'cd /boot && ls -l'

Если Вы включаете -v переключатель к ssh Вы видите то, что продолжается:

1-я команда:

debug1: команда Sending:/bin/sh-c "CD / загружают && ls-l"

2-я команда:

debug1: команда Sending:/bin/sh-c CD / загружают && ls-l

Обычно при отправке команд через ssh необходимо обратить особое внимание на заключение в кавычки и перенести кавычки в кавычках, поскольку различные слои снимают их. Также не потрудитесь отправлять /bin/sh.

Можно сделать очень полезную вещь, после того как Вы понимаете заключение в кавычки ssh такой как следующее. Это выполнит команду на удаленном сервере, но соберет результаты в файле локально в системе, куда Вы работали ssh команда:

$ ssh root@server 'free -m' > /tmp/memory.status

или это, где Вы смолите каталог на удаленном сервере и создаете его в локальной системе:

$ ssh remotehost 'tar zcvf - SOURCEDIR' | cat > DESTFILE.tar.gz

Ссылки

8
27.01.2020, 19:35

Обычно Вы не должны указывать что оболочку использовать. Это работает:

ssh user@host "cd /boot && pwd"

Но если Ваша оболочка по умолчанию проблематична, то просто удостоверяются, что Вы заключаете всю команду в кавычки, включая вызов оболочки. Любая из следующих работ

ssh user@host '/bin/sh -c "cd /boot && pwd"'
ssh user@host "/bin/sh -c \"cd /boot && pwd\""
5
27.01.2020, 19:35
  • 1
    Отметьте это в то время как cd /boot && pwd работы во всех оболочках главных семейств (Граница, csh, дистанционное управление), /bin/sh -c "cd /boot && pwd" не работал бы, если удаленная оболочка имеет rc семейство, где " не является особенным. –  Stéphane Chazelas 27.06.2013, 12:09