Saya akhirnya berhasil memecahkan masalah yang telah saya perjuangkan selama beberapa minggu. Saya menggunakan SSH dengan "kunci resmi" untuk menjalankan perintah dari jarak jauh. Semuanya baik-baik saja kecuali ketika saya melakukannya dalam loop sementara. Loop berakhir setelah menyelesaikan iterasi dengan perintah ssh.
Untuk waktu yang lama saya pikir ini adalah semacam keanehan ksh, tetapi saya sekarang menemukan bahwa bash sebenarnya berperilaku identik.
Program sampel kecil untuk mereproduksi masalah. Ini didistilasi dari implementasi yang lebih besar yang mengambil snapshot dan mereplikasi mereka di antara node dalam sebuah cluster.
#!/bin/bash
set -x
IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool
ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG " > /tmp/actionlist
#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
echo ${RMT_FILESYSTEM}@${MARKER}
[ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
echo Remote Command Return Code: $?
done
(Perhatikan ada karakter TAB dalam ekspresi pencarian grep sesuai definisi perilaku opsi "-H" dari daftar zfs.)
Sampel saya memiliki beberapa sistem file ZFS untuk root di mana semua "zona" memiliki sistem file root pada dataset bernama mirip dengan
POOL / zona / app1zone
POOL / zona / group2 / app2zone
dll.
Loop di atas harus membuat snapshot untuk masing-masing set data yang dipilih, tetapi sebagai gantinya hanya beroperasi pada yang pertama dan kemudian keluar.
Bahwa program menemukan jumlah dataset yang tepat dapat dengan mudah dikonfirmasi dengan memeriksa file "/ tmp / actionlist" setelah skrip ada.
Jika perintah ssh digantikan oleh, misalnya, perintah gema, maka loop berulang melalui semua jalur input. Atau favorit saya - tambahkan "echo" ke perintah yang menyinggung.
Jika saya menggunakan for for sebagai ganti maka itu juga berfungsi, tetapi karena ukuran potensial dari daftar dataset ini dapat menyebabkan masalah dengan panjang baris perintah diperluas maksimum.
Saya sekarang 99,999% yakin bahwa hanya loop dengan perintah ssh di dalamnya memberi saya masalah!
Perhatikan bahwa iterasi di mana perintah ssh berjalan, selesai! Seolah-olah data yang dimasukkan ke loop sementara tiba-tiba hilang ... Jika beberapa baris input pertama tidak melakukan perintah ssh, maka loop berjalan hingga benar-benar menjalankan perintah SSH.
Di laptop saya di mana saya menguji ini saya memiliki dua Solaris 10 VM dengan hanya sekitar dua atau tiga dataset sampel, tetapi hal yang sama terjadi pada sistem SPARC besar di mana ini dimaksudkan untuk ditayangkan, dan ada banyak dataset.
sumber
actionlist
. Cobalah untuk mengarahkan input standar ssh ke/dev/null
Jawaban:
SSH mungkin membaca dari input standar, memakan daftar tindakan Anda. Cobalah untuk mengarahkan input standar ssh ke / dev / null:
Sebagai aturan umum, ketika menjalankan perintah yang dapat mengganggu input standar di bawah
while read
-style loop, saya suka membungkus seluruh loop body menjadi braces:sumber
( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )
berbeda sama dengan kurung kurawal. Maksud saya dalam hal output yang dihasilkan, bukan tentang fakta bahwa kurung kurawal penutupan harus pada baris baru ...-n
opsi yang membuatnya (secara efektif) membuka kembali stdin dari / dev / null.sudo
dengan perintah di dalam loop?