Bagaimana melakukan ssh dengan batas waktu dalam skrip?

173

Saya menjalankan skrip yang terhubung melalui SSH tanpa kata sandi pada host jarak jauh. Saya ingin mengatur batas waktu, sehingga jika host jarak jauh mengambil waktu tak terbatas untuk dijalankan, saya ingin keluar dari sesi ssh dan melanjutkan baris lain dalam skrip sh saya.

Adakah yang tahu bagaimana melakukannya?

pengguna57421
sumber
Ini mungkin harus ditutup agar sejalan dengan penutupan duplikat lengkap cara mengurangi nilai batas waktu koneksi ssh [ditutup]
Murmel
Jika Anda dialihkan ke sini hanya untuk "tetap lebih banyak waktu di sshsesi Anda " (pertanyaan "Bagaimana cara meningkatkan batas waktu Koneksi SSH?"), Ini adalah tempat yang salah . Jawabannya ada di tautan ini tentang ssh-timeout .
Peter Krauss

Jawaban:

288
ssh -o ConnectTimeout=10  <hostName>

Di mana 10 adalah waktu dalam detik. Batas waktu ini hanya berlaku untuk pembuatan koneksi.

pengguna57421
sumber
4
ConnectTimeout hanya menetapkan batas waktu pada pengaturan koneksi, kan?
Aurélien Ooms
10
Ini tidak benar-benar bekerja untuk "host jarak jauh mengambil waktu yang tak terbatas untuk menjalankan": "ssh -o ConnectTimeout = 5 host 'tidur 10'" menunggu selama 10 detik, bukan 5.
Ferry Boender
109

Gunakan -o ConnectTimeoutdan -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout menjaga agar skrip tidak menggantung, BatchMode membuatnya tidak menggantung dengan Host tidak dikenal, YES untuk menambahkan ke known_hosts, dan StrictHostKeyChecking menambahkan sidik jari secara otomatis.

**** CATATAN **** "StrictHostKeyChecking" hanya ditujukan untuk jaringan internal tempat Anda mempercayai host Anda. Bergantung pada versi klien SSH, "Anda yakin ingin menambahkan sidik jari" dapat menyebabkan klien menggantung tanpa batas waktu (terutama versi lama yang berjalan pada AIX). Sebagian besar versi modern tidak menderita masalah ini. Jika Anda harus berurusan dengan sidik jari dengan beberapa host, saya sarankan untuk menjaga file known_hosts dengan semacam alat manajemen konfigurasi seperti boneka / boneka / koki / garam / dll.

Doug
sumber
11
Tidak hanya -o StrictHostKeyChecking=notidak menjawab pertanyaan, tetapi itu ide yang buruk jika Anda peduli dengan keamanan, yang mungkin menjadi alasan Anda menggunakan SSH.
Dolph
9
Adalah baik untuk menunjukkan kemungkinan implikasi keamanan dari -o StrictHostKeyChecking = tidak. Namun, itu akan mencegah skrip menggantung selama eksekusi.
Doug
2
PERINGATAN!!!! Seperti yang ditulis @Dolph, JANGAN gunakan StrictHostKeyChecking=nojika Anda peduli dengan keamanan sama sekali. @Doug: skrip tidak akan hang - itu hanya akan bersikeras bahwa Anda ssh ke host jarak jauh secara manual pertama kali, sehingga mengenal host. Tapi itu akan melindungi Anda dari serangan MITM. Harap edit jawaban ini untuk mencerminkannya karena ini saran yang sangat berbahaya. Dan itu bahkan tidak diminta.
johndodo
2
Memperbarui jawaban saya. Dari pengalaman saya, itu dapat menyebabkan beberapa klien hang.
Doug
50

coba ini:

timeout 5 ssh user@ip

timeout mengeksekusi perintah ssh (dengan args) dan mengirimkan SIGTERM jika ssh tidak kembali setelah 5 detik. untuk detail lebih lanjut tentang batas waktu, baca dokumen ini : http://man7.org/linux/man-pages/man1/timeout.1.html

atau Anda dapat menggunakan param ssh:

ssh -o ConnectTimeout=3 user@ip
Lee HoYo
sumber
4
Jika Anda mencari perintah ini di Mac, coba brew install coreutilsdan kemudian gunakan gtimeout (sumber: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
larcher
3
Ini mungkin tidak melakukan apa yang Anda inginkan. Pertimbangkan perintah timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Ini membunuh proses di sisi klien SSH, tetapi / tmp / blarg masih akan dimodifikasi pada server jauh. Ini berarti bahwa jika Anda menjalankan pekerjaan intensif CPU pada server jarak jauh, Anda akan membocorkan proses.
Jamie Davis
1
@JamieDavis bagaimana dengan pengguna ssh @ server 'timeout 5s sleep 10'?
Filipin
18

Anda juga dapat terhubung dengan bendera

-o ServerAliveInterval = <secs>
jadi klien SSH akan mengirim paket nol ke server setiap <secs>detik, hanya untuk menjaga koneksi tetap hidup. Di Linux ini juga dapat diatur secara global /etc/ssh/ssh_configatau per pengguna di ~/.ssh/config.

Patrizio Bertoni
sumber
4
Kedengarannya seperti kebalikan dari apa yang diminta pertanyaan.
Davor Cubranic
1

Jika semuanya gagal (termasuk tidak memiliki timeoutperintah) konsep dalam skrip shell ini akan berfungsi:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi
Philip Kearns
sumber
0

Nah, Anda bisa menggunakan nohup untuk menjalankan apa pun yang Anda jalankan pada 'mode non-blocking'. Jadi, Anda bisa terus memeriksa apakah apa pun yang seharusnya dijalankan, dijalankan, atau keluar.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Script berakhir pada 15 Feb 2011, 9:20 AM"> /tmp/done.txt

Jadi yang kedua Anda hanya memeriksa apakah file tersebut ada.

Eduardo
sumber
Masuk akal. tetapi, skrip yang sedang berjalan memberi saya beberapa keluaran, yang ditampilkan di konsol .. bagaimana cara memeriksa apakah skrip saya sebelumnya berjalan atau keluar? $? atau sesuatu yang lain ?
user57421
Yah Anda bisa membuat skrip itu membuat file setelah selesai. Saya telah menambahkan komentar pada jawabannya .... grrr
Eduardo