我有一些简单的脚本,用于菊花链连接在一组服务器上运行特定脚本,所有服务器都列在文件中,每行一个。
单服务器部署脚本包含以下内容:
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个主机上成功运行,所以我认为这是sd一旦ssh发生时stdio被切断的事情。另外tcgatattr错误让我有点担心。
我该如何解决这个问题?究竟是什么导致tcgetattr错误(我甚至不确定它是否相关)? 没有真正用shell脚本做很多事情,很抱歉,如果我遗漏了一些非常明显的东西,我们将不胜感激。
答案 0 :(得分:1)
当作为子进程的一部分运行时,ssh重用stdin文件描述符是一个问题。
解决方法是在从非终端上下文调用ssh时使用'-n'。
option=-n
tty -s 2>/dev/null && option=
scp ${file} ${host}:/tmp/
ssh $option -t ${host} /tmp/${file}
ssh $option ${host} rm /tmp/${file}
答案 1 :(得分:0)
我通过使用bash数组暂时将行存储到数组中以避免stdin中断来解决这个问题...但是感觉不对...如果有人有更好的解决方法,请告诉我。< / p>
这是我的解决方案:
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