Почему скрипт развертывания bash loop работает только один раз? - PullRequest
0 голосов
/ 13 апреля 2010

У меня есть несколько простых сценариев, предназначенных для последовательного соединения, чтобы запустить определенный сценарий на наборе серверов, перечисленных в файле, по одному на строку.

Сценарий развертывания одного сервера содержит следующее:

  1 #!/bin/bash
  2 
  3 file=$1
  4 host=$2
  5 
  6 scp ${file} ${host}:/tmp/
  7 USER=`whoami`
  8 ssh -t -t $USER@${host} /tmp/${file}
  9 
 10 ssh "${host}" /bin/rm /tmp/${file}
 11 exit

Отлично работает на скрипте, который у меня есть, yum устанавливает конфиги tomcat и symlinks hadoop / hbase в каталог общего класса.

Второй основной файл - deploy-all.sh, предназначенный для анализа списка хостов и запуска сценария развертывания для всех них:

  1 #!/bin/bash
  2 
  3 script=$1
  4 
  5 cat dumbo-hosts | while read fileline
  6 do
  7 echo ${fileline}
  8 ./deploy.sh ${script} ${fileline}
  9 
 10 sleep 10
 11 done

В результате сценарий запускается один раз, а затем цикл for прерывается ... Я получил что-то вроде следующего вывода:

$ ./deploy-all.sh setup-tomcat.sh 
line is hadoop01.myhost
setup-tomcat.sh                               100%  455     0.4KB/s   00:00    
tcgetattr: Inappropriate ioctl for device
hadoop02.myhost
hadoop03.myhost
hadoop04.myhost
<succesful output of hadoop01 task>
...
Connection to hadoop01.myhost closed.

Если я закомментирую команды ssh, цикл успешно пройдет через все 4 хоста, поэтому я предполагаю, что это связано с тем, что stdio будет отключен после возникновения ssh. Кроме того, меня немного беспокоит ошибка tcgatattr.

Как я могу обойти это? Что именно вызывает ошибку tcgetattr (я даже не уверен, что это связано)? На самом деле не так уж много сделано со скриптами оболочки, так что извините, если я упустил что-то действительно очевидное, любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 13 апреля 2010

Проблема в том, что ssh повторно использует дескриптор файла stdin при запуске как часть подпроцесса.

Обходной путь должен использовать '-n' при вызове ssh из нетерминального контекста.

option=-n
tty -s 2>/dev/null && option=

scp ${file} ${host}:/tmp/
ssh $option -t ${host} /tmp/${file}
ssh $option ${host} rm /tmp/${file}
0 голосов
/ 13 апреля 2010

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

Вот мое решение:

  1 #/bin/bash
  2 
  3 #myscript = $1
  4 count=0
  5 
  6 declare -a lines
  7 
  8 while read line
  9 do
 10   lines[$count]=$line
 11   ((count++))
 12 done < dumbo-hosts
 13 
 14 for i in "${lines[@]}"
 15 do
 16   echo "$i"
 17   ./deploy.sh "$1" "${i}"
 18 done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...