У меня есть система, в которую я могу войти только под своим именем пользователя (myuser), но мне нужно запускать команды от имени другого пользователя (scriptuser). До сих пор я придумал следующее для запуска необходимых мне команд:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
Однако, если я пытаюсь выполнить более сложную команду, например, у [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
меня быстро возникают проблемы с цитированием. Я не уверен, как можно передать этот пример сложной команды bash -c
, когда \"
уже разграничивает границы команды, которую я передаю (и поэтому я не знаю, как заключить в каталог / tmp / Some каталог, который содержит пробелы.
Есть ли общее решение, позволяющее мне передавать любую команду независимо от того, насколько сложным / сумасшедшим является цитирование, или это какое-то ограничение, которого я достиг? Есть ли другие возможные и, возможно, более читаемые решения?
Ответы:
Уловка, которую я иногда использую, состоит в том, чтобы использовать base64 для кодирования команд и передать его в bash на другом сайте:
Это закодирует скрипт с любыми запятыми, обратными слешами, кавычками и переменными внутри безопасной строки и отправит его на другой сервер. (
-w0
требуется отключить перенос строки, что по умолчанию происходит в столбце 76). С другой стороны,$(base64 -d)
декодирует скрипт и передает его в bash для выполнения.У меня никогда не было с этим проблем, независимо от того, насколько сложным был сценарий. Решает проблему с побегом, потому что вам не нужно ничего избегать. Он не создает файл на удаленном хосте, и вы можете легко запускать чрезвычайно сложные сценарии.
источник
ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash"
base64 script | ssh remotehost 'base64 -d | sudo bash'
было бы достаточно :)Видишь
-tt
вариант? Прочтитеssh(1)
руководство.Я часто использую vim и использую
:!cat % | ssh -tt somemachine
трюк.источник
:!cat % | (command)
можно сделать как:w !(command)
или:!(command) < %
.ssh -tt
заставляет мой ssh не завершать работу после выполнения определенных команд (добавлениеexit
в конце не помогает)Я думаю, что самое простое решение заключается в модификации комментария @ thanasisk.
Создайте скрипт
scp
на машине, затем запустите его.Иметь скрипт
rm
в самом начале. Оболочка открыла файл, поэтому он был загружен, и его можно без проблем удалить.Делая вещи в таком порядке (во-
rm
первых, другие вещи, во-вторых), он будет даже удален, когда в какой-то момент произойдет сбой.источник
Вы можете использовать
%q
спецификатор формата с,printf
чтобы позаботиться о экранировании переменной для вас:printf -v
записывает вывод в переменную (в данном случае$cmd_str
). Я думаю, что это самый простой способ сделать это. Нет необходимости передавать какие-либо файлы или кодировать командную строку (насколько мне нравится трюк).Вот более сложный пример, показывающий, что он работает и для таких вещей, как квадратные скобки и амперсанды:
Я не проверял это с,
sudo
но это должно быть так просто, как:Если вы хотите, вы можете пропустить шаг и избежать создания промежуточной переменной:
Или даже просто избегайте создания переменной полностью:
источник
Вот «правильный» (синтаксический) способ выполнить что-то подобное в bash:
Подробное объяснение того, как это работает, см. На странице https://stackoverflow.com/a/21761956/111948.
источник
Знаете ли вы, что вы можете использовать,
sudo
чтобы дать вам оболочку, где вы можете запускать команды в качестве выбранного пользователя?источник
Вы можете определить скрипт на локальном компьютере, а затем
cat
передать его на удаленный компьютер:источник
sudo -u scriptuser
? Можно ли использовать heredoc, учитывая, что в сценарии, который я бы передавал на машину, должны быть переменные?echo "sudo `cat fileForSsh.txt`" | ssh ...
но я продолжаю получатьsudo: sorry, you must have a tty to run sudo
./etc/sudoers
изменить файлssh -tq user@host "sudo bash -s" < test.sh
Просто и легко.
источник
Если вы используете достаточно современную оболочку Bash, вы можете поместить свои команды в функцию и распечатать эту функцию в виде строки, используя
export -p -f function_name
. Результат этой строки может содержать произвольные команды, которые не обязательно должны запускаться от имени пользователя root.Пример использования каналов из моего ответа на Unix.SE :
Пример, который извлекает, сохраняет файл для пользователя входа в систему и устанавливает программу в корне:
Если вы хотите выполнить всю команду с помощью
sudo
, вы можете использовать это:источник
Вот мое (не очень проверенное) дрянное решение для этого:
Не можете сделать:
Следующим шагом является создание
betterssh
сценария, который уже делает это:источник
Для тех из вас, кому необходимо передать параметры в сценарий, это должно быть следующим:
источник
Сначала создайте локальный скрипт, а затем выполните его удаленно, используя следующую команду:
источник