считайте-e в sub сценарии

[113421] Ключи RSA были бы лучшим решением, Однако, если вы не можете их использовать, вам нужно сделать несколько уродливых взломов с [113866] ожиданием[113867], как это:[12179]Сохраните его как ssh.exp и запустите как:[12180]
2
17.03.2015, 03:44
3 ответа

Мысль: Вы бегаете Bash с трубой к стандартному входу. И тогда вы просите это читать с стандартного ввода. Это не будет работать.

Вместо этого используйте названную трубу?

ETA: Или, может быть, нет ...

mkfifo ~/tmp-pipe
wget -O - https://raw.githubusercontent.com/caarlos0/dotfiles/install/script/install > ~/tmp-pipe &
bash ~/tmp-pipe
rm ~/tmp-pipe

К этому времени, если вы также хотите убедиться, что вы не растоптелируете в некоторых существующих файлах, вы также можете использовать TempFile: Будет менее беспорядок, чтобы иметь дело с:

P=$( mktemp )
wget -O - https://raw.githubusercontent.com/caarlos0/dotfiles/install/script/install > $P &
bash $P
rm $P

да. Понятия не имею.

0
27.01.2020, 22:55

Стандартный вход процесса Bash - это скрипт, который загружен WGET. Таким образом, звонок на прочитал считывает линию из этого скрипта или ничего не читает, если Bash уже закончил скрипт.

Wget -O - ... | Bash может быть милым одноклассником, но это не хорошая идея. Если разрывы загрузки в середине, Bash будет выполнять часть сценария, которая может быть загружена, и ошибка с Wget может быть трудно обнаружить. Было бы лучше сначала загрузить файл, а затем выполнить его:

wget https://…/install
bash install
rm install

Чтобы избежать явного создания временного файла, вместо этого вы можете использовать замену процесса. Это требует вашей интерактивной оболочки для поддержки замены процесса: он должен быть Bash, KSH93 или ZSH. Это страдает от того же самого нижнего дна, поскольку труба сценарий будет выполнен, даже если загрузка прерывается, но она не захватывает стандартный вход, который остается терминалом.

bash <(wget -O - …)

Если вы хотите, чтобы ваш скрипт поддерживать WGET -O - ... | Bash Метод трубы, затем вы можете сделать скрипт читать с терминала, наложив Exec . Тем не менее, это плохая идея, которая заставит многих пользователей проклинать вас, потому что это делает невозможным автоматизировать работу скрипта, просто подавая его ответы на его стандартный вход - вместо этого нужно будет использовать такой инструмент Ожидайте , чтобы запустить скрипт в терминале даже для автоматического использования.

Опция -I - I - это неактуальный: Bash не работает в интерактивном режиме, потому что он работает скрипт, а стандартный вход не является терминалом, потому что он перенаправлен с трубы. Включение -I -I -I делает Bash притворяться, что он используется интерактивно, даже если его пропускают скрипт на своем стандартном входе; Это не изменяет тот факт, что стандартный вход не терминал.

Кстати, это не имеет ничего общего с тем, что сценарий разделен в два.Вы увидите точно такие же вещи, если код из скрипта 2 был в главном сценарии.

0
27.01.2020, 22:55

Другие упоминали, что ваш стандартный ввод заменяется потоковым скриптом. Это обычная проблема, но ее легко решить:

bash 3<&0 <<\SCRIPT          #ref stdin in fd 3, replace stdin w/ SCRIPT
    echo Doing some stuff... #do your stuff
    printf "\r  [ \033[0;33m?\033[0m ] What is your name? "
    read -e name <&3         #read from original stdin
    echo "$name"
    echo Done
SCRIPT

В приведенной выше последовательности я использую heredoc вместо вашего конвейерного скрипта. Поскольку канал еще не заменил приведенный выше стандартный ввод bash на то, что было до (обычно терминал) , приведенное выше просто немного менее сложно, чем ваш сценарий должен быть. Но я хотел продемонстрировать, как это будет работать, и это самый простой способ.

Когда вызывается bash , все процессы, которые он запускает позже, наследуют все его fds - если вы явно не > & - их не закроете.Итак, если вы просто выполните простое перенаправление во время вызова, это перенаправление будет передаваться всем дочерним элементам. Путем дублирования fd 0 в fd 3 можно позже прочитать <& 3 тот же самый fd без необходимости делать что-либо раздражающее, например - хотя последнее может Это хорошая идея в том случае, если у вас есть веская причина взаимодействовать с пользователем за клавиатурой, а не то, что этот пользователь может вам передать.

В любом случае, стандартный вывод по-прежнему будет идти в то же место, поэтому все данные echo / printf будут печататься в любом исходящем потоке, который был бы в противном случае, но bash будет возьмите stdin из потокового скрипта, и любые другие ссылки на него должны быть явными.

С вашей трубкой вам понадобится еще один слой:

{ wget ... | bash; } 3<&0

Это будет работать примерно так же. Для этого вам не нужно явно ссылаться на поток <& 3 для read (или любой другой команды) :

{   {   echo "script$$(){"
        wget ...
        printf "\n} <&3; script$$\n"
} |     bash
} 3<&0

Таким образом вы фактически определяете функция, которая содержит весь ваш конвейер в сценарии и явно перенаправляет ваш сохраненный stdin на stdin функции после того, как вы прочитали все это, , затем вы его вызываете. Таким образом, все команды внутри будут рассматривать <& 3 как ваш стандартный ввод, и вам не нужно каким-либо образом изменять его содержимое, чтобы ссылаться на него, но вы все равно можете прочитать все это через стандартный ввод.

0
27.01.2020, 22:55

Теги

Похожие вопросы