Назад | Перейти на главную страницу

Выполнять локальные сценарии bash на удаленном сервере, но требует ввода данных пользователем

Я использую команду SSH для удаленного выполнения сценариев bash:

ssh user@server 'bash -s' < $script_dir/script.sh

А внутри script.sh у меня будет команда, как показано ниже, для добавления ключей ssh:

ssh-keygen -t rsa
ssh-copy-id postgres@$sqlserver
ssh postgres@$sqlserver -C true

А также создать пользователя на удаленном сервере sql

printf "Creating user in postgresql server...\n"
createuser -s -P username

Которые требуют ввода пользователя, но я обнаружил, что, когда я выполняю команду с удаленного сервера, он пропускает ввод данных пользователя и терпит неудачу.

Еще один:

printf "Please enter your barman server name: \n" ; read -s barmanserver

Который также не может читать ввод пользователя

Я знаю, что сценарий, похоже, не может читать ввод другого терминала, но может ли кто-нибудь помочь мне найти решение, если мне нужно, чтобы пользовательский ввод продолжался?

Большое спасибо!!

Ева

Метод, который вы используете для удаленного выполнения скрипта, генерирует конфликт между кодом и потоками данных. То есть ... Во время казни ssh user@server 'bash -s' < $script_dir/script.sh, вы выделяете стандартный ввод (STDIN) для кода, который будет выполняться удаленно. Но если исполняемому коду требуется ввод данных, он будет передан в следующей строке кода (поскольку STDIN передает строки кода удаленному bash обработать).

Если вы хотите использовать STDIN для передачи входных данных в сценарий, который выполняется удаленно, вам, возможно, придется использовать другой поток для кода. OpenSSH, похоже, еще не имеет встроенной функции пересылки файловых дескрипторов, то есть STDIN (файловый дескриптор номер 0) кажется единственным файловым дескриптором, который можно использовать для пересылки данных с локального терминала в удаленный сеанс. В качестве обходного пути вы можете заранее скопировать файл сценария, например:

scp $script_dir/script.sh user@server:/home/user/$script_dir/script.sh && \
ssh user@server /home/user/$script_dir/script.sh

Или вы можете использовать взлом Bash, чтобы не записывать локальный код в удаленную файловую систему. Например:

cat $script_dir/script.sh - | ssh user@server \
bash \<\( head -c `wc -c < $script_dir/script.sh` \)

PS: Взлом выше не оптимален, потому что:

  • Это не работает, если SSH запрашивает данные аутентификации, такие как пароль пользователя или ключевую парольную фразу;

  • Локальный сеанс требует дополнительной строки ввода после окончания удаленного выполнения.

Сценарий Expect используется для автоматической подачи ввода, вы можете использовать этот сценарий для своего сценария, указанная ссылка для более подробной информации: https://www.thegeekstuff.com/2010/10/expect-examples/

Со страниц руководства ssh:

-t 'Принудительное выделение псевдо-tty. Это можно использовать для выполнения произвольных экранных программ на удаленном компьютере, что может быть очень полезно, например при реализации услуг меню. Несколько параметров -t принудительно выделяют tty, даже если ssh не имеет локального tty.

ssh -t user@server 'bash -s' < $script_dir/script.sh