Невозможно выполнить команду через ssh

Невозможно выполнить команду через ssh

Я запускаю команду на машине FreeBSD (xxx.yyy.zzz.net) и получаю вывод

команда

sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

выход

media RPM             non-rotating
media RPM             non-rotating
media RPM             non-rotating

Я пытаюсь запустить ту же команду через ssh с другой машины.

команда

ssh xxx.yyy.zzz.net sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

ошибка

sudo: camcontrol: command not found

решение1

В вашей команде каждый |интерпретируется вашей локальной оболочкой. Последний аргумент sshвидит devlist. sshвызывается локально (это неудивительно), но так же и все после первого |.

Ошибка, которую вы получили, возникла из sudoэтого фрагмента: do sudo camcontrol identify $aОн запускается локально и, по-видимому, camcontrolнедоступен на локальной машине.

Вам нужно правильное экранирование или кавычки. В этом случае вы можете захотеть заключить всю удаленную команду в одинарные кавычки:

ssh xxx.yyy.zzz.net 'sudo camcontrol devlist | grep -o "ada[0-9]" | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done'

Обратите внимание, что я изменил одинарные кавычки, которые у вас уже были. (Добавленные) одинарные кавычки не только группируют всю строку, так что sshполучают ее; они также предотвращают локальное расширение $a.

Если sudoсобирается запросить ваш пароль, ему понадобится псевдотерминал. Вы можете принудительно выделить псевдотерминал с -tопцией ssh(чтобы это выглядело как ssh -t xxx.yyy.zzz.net …). Примечание ssh -tвыделяет псевдотерминал на удаленной стороне. Удаленные sudoприглашения в его stderr, но затем stdout и stderr «выводятся» этим псевдотерминалом (как они обычно выводятся на консоль), и в этот момент вы больше не можете их различать; объединенный поток захватывается и передается на локальную сторону, где он идет в stdout. Без удаленного stdout и stderr, которые передаются -tотдельно, перейдите в stdout и stderr на локальной стороне, и они в конечном итоге объединяются (или нет, если перенаправлены) в то, что вы видите. Это означает, что с -tвы не можете (на локальной стороне) отличить удаленный stderr от удаленного stdout. Если вам нужно локально обработать (перенаправить) вывод дальше, и вы используете, -tто любое приглашение из sudoбудет мешать.

Также вам, вероятно, захочется использовать двойные кавычки $a(даже в первой команде, которая не использует ssh). СмотритеПочему мой скрипт оболочки тормозит пробелы и другие специальные символы?

Связанный контент