сценарий цикла выполняется только один раз — Bash

#bash #hadoop

#bash #hadoop

Вопрос:

У меня есть следующий bash сценарий:

 #!/bin/bash
cat /etc/hadoop/conf.my_cluster/slaves | 
while read CMD; do
    ssh -o StrictHostKeyChecking=no ubuntu@$CMD "sudo service hadoop-0.20-mapreduce-tasktracker restart"
    ssh -o StrictHostKeyChecking=no ubuntu@$CMD "sudo service hadoop-hdfs-datanode restart"
    echo $CMD
done
 

/etc/hadoop/conf.my_cluster/slaves имеет IP-адрес 5 подчиненных компьютеров. datanode Не удалось связаться с jobtracker , поэтому решение состоит в том, чтобы перезапустить его.
Вывод:

 ubuntu@domU-12-31-39-07-D6-DE:~$ ./test.sh 
Warning: Permanently added '54.211.5.233' (ECDSA) to the list of known hosts.
 * Stopping Hadoop tasktracker: 
stopping tasktracker
 * Starting Hadoop tasktracker: 
starting tasktracker, logging to /var/log/hadoop-0.20-mapreduce/hadoop-hadoop-tasktracker-domU-12-31-39-06-8A-27.out
Warning: Permanently added '54.211.5.233' (ECDSA) to the list of known hosts.
 * Stopping Hadoop datanode: 
stopping datanode
 * Starting Hadoop datanode: 
starting datanode, logging to /var/log/hadoop-hdfs/hadoop-hdfs-datanode-domU-12-31-39-06-8A-27.out
54.211.5.233
 

Однако из 5 IP-адресов, которые он должен был запускать, выполняется только первый. Как я мог это исправить?

Комментарии:

1. Вы могли бы использовать while read -r CMD; do ...; done < /etc/hadoop/conf.my_cluster/slaves вместо cat /etc/hadoop/conf.my_cluster/slaves; do ...; done . Нет необходимости использовать cat с таким циклом;)

Ответ №1:

Давайте спросим shellcheck:

 $ shellcheck yourscript

In yourscript line 3:
while read CMD; do
^-- SC2095: ssh may swallow stdin, preventing this loop from working properly.

In yourscript line 4:
    ssh -o StrictHostKeyChecking=no ubuntu@$CMD [...]
    ^-- SC2095: Add < /dev/null to prevent ssh from swallowing stdin.
 

И вот что вы делаете.

Комментарии:

1. Или используйте ssh -n option — cite from man ssh: «Перенаправляет stdin из /dev/null (фактически, предотвращает чтение из stdin)».