for
Döngü burada gayet iyi. Ancak bunun, dosyanın boşluk karakterleri veya globbing karakterleri içermeyen makine isimlerini içerdiğinden kaynaklandığını unutmayın. genel olarak for x in $(cat file); do …
çizgileri üzerinde yineleme yapmak için çalışmaz file
, çünkü kabuk önce çıktıyı komuttan cat file
boşluk olan herhangi bir yere böler ve sonra her kelimeyi bir küre şekli olarak ele alır, böylece \[?*
daha da genişler. Üzerinde for x in $(cat file)
çalışırsanız güvenli yapabilirsiniz :
set -f
IFS='
'
for x in $(cat file); do …
İlgili okuma: Adlarda boşluk bulunan dosyalar arasında dolaşmak. ; Bir değişkenden bash satır satır satır nasıl okuyabilirim? ; Bunun yerine neden while IFS= read
bu kadar sık kullanılıyor IFS=; while read..
? Kullanırken while read
, satırları okumak için güvenli sözdizimi olduğunu unutmayın while IFS= read -r line; do …
.
Şimdi, while read
denemenizde neyin yanlış gittiğine bakalım . Sunucu listesi dosyasından yeniden yönlendirme, tüm döngüye uygulanır. Yani ssh
çalıştığında, standart girdi o dosyadan gelir. Ssh istemcisi, uzak uygulamanın ne zaman standart girişinden okumak isteyebileceğini bilemez. Böylece ssh istemcisi bazı girişleri fark ettiğinde, o girişi uzak tarafa gönderir. Buradaki ssh sunucusu bu girişi isterse uzak komuta beslemeye hazırdır. Sizin durumunuzda, remote komutu hiçbir zaman herhangi bir girişi okumaz, böylece veriler biter, ancak müşteri tarafı bunun hakkında hiçbir şey bilmez. echo
Çalıştığınız girişim echo
hiç bir girişi okumadığı için standart girişi tek başına bırakır.
Bundan kaçınmanın birkaç yolu vardır. Ssh -n
seçeneğine standart girdiden okumamasını söyleyebilirsiniz .
while read server; do
ssh -n $server "uname -a"
done < /home/kenny/list_of_servers.txt
-n
Aslında seçenek söyler ssh
onun girişini yönlendirmek için /dev/null
. Bunu kabuk düzeyinde yapabilirsiniz ve herhangi bir komut için işe yarar.
while read server; do
ssh $server "uname -a" </dev/null
done < /home/kenny/list_of_servers.txt
Önlemek ssh'nin giriş dosyasından çıkan A cazip yöntem üzerinde yeniden yönlendirme koymaktır read
komutu: while read server </home/kenny/list_of_servers.txt; do …
. Bu çalışmaz, çünkü read
komut her çalıştırıldığında dosyanın tekrar açılmasına neden olur (böylece dosyanın ilk satırını tekrar tekrar okuyacaktır). Yeniden yönlendirmenin tüm döngü boyunca olması gerekir, böylece dosya döngü süresince bir kez açılır.
Genel çözüm, standart girdi dışındaki bir dosya tanımlayıcısındaki döngüye girdi sağlamaktır . Kabuk, giriş ve çıkışı bir tanımlayıcı numaradan diğerine feribot yapacak şekilde inşa edilmiştir. Burada dosyayı dosya tanımlayıcı 3'te açıyoruz ve read
komutun standart girişini dosya tanımlayıcı 3'ten yeniden yönlendiriyoruz . Ssh istemcisi standart olmayan açıklayıcıları görmezden geliyor.
while read server <&3; do
ssh $server "uname -a"
done 3</home/kenny/list_of_servers.txt
Bash'ta, read
komutun farklı bir dosya tanımlayıcısından okumak için belirli bir seçeneği var, böylece yazabilirsiniz read -u3 server
.
İlgili okuma: Dosya tanımlayıcıları ve kabuk komut dosyası ; Ne zaman ek bir dosya tanımlayıcı kullanırsınız?