Saya mencari metode cepat dan sederhana untuk pengujian dengan benar jika port TCP yang diberikan terbuka pada server jarak jauh, dari dalam skrip Shell.
Saya sudah berhasil melakukannya dengan perintah telnet, dan berfungsi dengan baik ketika port dibuka, tetapi sepertinya tidak timeout ketika tidak dan hanya hang di sana ...
Berikut ini contohnya:
l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"`
if [ "$?" -ne 0 ]; then
echo "Connection to $SERVER on port $PORT failed"
exit 1
else
echo "Connection to $SERVER on port $PORT succeeded"
exit 0
fi
Saya juga membutuhkan cara yang lebih baik, atau cara untuk memaksa telnet ke timeout jika tidak terhubung di bawah 8 detik misalnya, dan mengembalikan sesuatu yang dapat saya tangkap di Shell (kode pengembalian, atau string di stdout).
Saya tahu metode Perl, yang menggunakan modul IO :: Socket :: INET dan menulis skrip yang berhasil yang menguji port, tetapi lebih suka menghindari menggunakan Perl jika mungkin.
Catatan: Inilah yang dijalankan server saya (dari mana saya harus menjalankan ini)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Jawaban:
Seperti yang ditunjukkan oleh B. Rhodes,
nc
akan melakukan pekerjaan. Cara yang lebih ringkas untuk menggunakannya:Dengan cara
nc
itu hanya akan memeriksa apakah port terbuka, keluar dengan 0 pada keberhasilan, 1 pada kegagalan.Untuk pemeriksaan interaktif cepat (dengan batas waktu 5 detik):
sumber
-G#
untuk mengatur batas waktu koneksi terpisah dari / selain-w#
batas waktu, yang pada dasarnya berfungsi sebagai batas waktu baca.-z
opsi. Anda mungkin ingin mempertimbangkan: unix.stackexchange.com/questions/393762/…Ini cukup mudah untuk dilakukan dengan opsi
-z
dan , tetapi tidak semua sistem telah diinstal. Jika Anda memiliki versi bash yang cukup baru, ini akan berfungsi:-w TIMEOUT
nc
nc
Apa yang terjadi di sini adalah
timeout
menjalankan sub-perintah dan membunuhnya jika tidak keluar dalam batas waktu yang ditentukan (1 detik dalam contoh di atas). Dalam hal inibash
adalah sub-perintah dan menggunakan penanganan khusus / dev / tcp untuk mencoba dan membuka koneksi ke server dan port yang ditentukan. Jikabash
dapat membuka koneksi dalam batas waktu,cat
hanya akan segera menutupnya (karena itu membaca dari/dev/null
) dan keluar dengan kode status0
yang akan menyebar melaluibash
dan kemudiantimeout
. Jikabash
mendapat kegagalan koneksi sebelum batas waktu yang ditentukan, makabash
akan keluar dengan kode keluar 1 yangtimeout
juga akan kembali. Dan jika bash tidak dapat membuat koneksi dan batas waktu yang ditentukan berakhir, makatimeout
akan membunuhbash
dan keluar dengan status 124.sumber
/dev/tcp
tersedia di sistem selain Linux? Bagaimana dengan Mac khususnya?timeout
juga tidak ada di FreeBSD, dan pada kotak Ubuntu lama saya ini adalah paket yang dapat diinstal, tetapi tidak ada di sana secara default. Akan lebih bagus jika ada cara untuk melakukan ini di bash sendirian, tanpa alat pihak ketiga seperti batas waktu atau netcat.timeout
muncul untuk menjadi bagian dari coreutils GNU, dan dapat diinstal pada Mac dengan homebrew:brew install coreutils
. Ini akan tersedia sebagaigtimeout
.bash-2.04-devel
, meskipun dukungan untuk nama host mungkin telah ditambahkanbash-2.05-alpha1
.TOC:
timeout
nc
Menggunakan bash dan
timeout
:Catatan yang
timeout
harus hadir dengan RHEL 6+, atau alternatifnya ditemukan di GNU coreutils 8.22. Di MacOS, instal menggunakanbrew install coreutils
dan gunakan sebagaigtimeout
.Perintah:
Jika parametrizing host dan port, pastikan untuk menentukannya seperti
${HOST}
dan${PORT}
seperti di atas. Jangan menentukan mereka hanya sebagai$HOST
dan$PORT
, yaitu tanpa kawat gigi; itu tidak akan berfungsi dalam kasus ini.Contoh:
Keberhasilan:
Kegagalan:
Jika Anda harus mempertahankan status keluar dari
bash
,Menggunakan
nc
:Perhatikan bahwa versi mundur yang tidak kompatibel
nc
terinstal di RHEL 7.Perintah:
Perhatikan bahwa perintah di bawah ini unik karena identik untuk RHEL 6 dan 7. Hanya instalasi dan output yang berbeda.
RHEL 6 (nc-1.84):
Instalasi:
Contoh:
Keberhasilan: Kegagalan:Jika nama host dipetakan ke beberapa IP, perintah gagal di atas akan menggilir banyak atau semua dari mereka. Sebagai contoh:
RHEL 7 (nmap-ncat-6.40):
Instalasi:
Contoh:
Keberhasilan: Kegagalan:Jika nama host dipetakan ke beberapa IP, perintah gagal di atas akan menggilir banyak atau semua dari mereka. Sebagai contoh:
Catatan:
The
-v
(--verbose
) argumen danecho $?
perintah tentu saja hanya untuk ilustrasi.sumber
timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
adalah poin yang bagus!2>&1
ke tidak status gemaresult_test=$(nc -w 2 $ip_addreess 80 </dev/null 2>&1 ; echo $?)
Dengan
netcat
Anda dapat memeriksa apakah port terbuka seperti ini:Nilai balik
nc
akan berhasil jika port TCP dibuka, dan kegagalan (biasanya kode pengembalian 1) jika tidak dapat membuat koneksi TCP.Beberapa versi
nc
akan hang ketika Anda mencoba ini, karena mereka tidak menutup setengah pengiriman soket mereka bahkan setelah menerima file akhir dari/dev/null
. Di laptop Ubuntu saya sendiri (18.04),netcat-openbsd
versi netcat yang saya instal menawarkan solusi:-N
opsi diperlukan untuk mendapatkan hasil langsung:sumber
nc
yang tidak mendukung-w
bendera.-z
dukungan - berfungsi di RHEL / CentOS 7, misalnya-w
perlu, gagal dimana perintah ketika digunakan dalam skrip dapat bertahan selama lebih dari sepuluh detik. Saya telah menulis jawaban yang mencakup-w
.nc host port -w 2 && echo it works
nc -vz localhost 3306
. Ini memberikan output yang lebih verbose. Mencobanya di mac saja.Di Bash menggunakan file perangkat semu untuk koneksi TCP / UDP langsung. Ini skripnya:
Pengujian:
Berikut ini adalah satu-liner (sintaks Bash):
Perhatikan bahwa beberapa server dapat dilindungi firewall dari serangan banjir SYN, sehingga Anda mungkin mengalami batas waktu koneksi TCP (~ 75secs). Untuk mengatasi masalah batas waktu, coba:
Lihat: Bagaimana cara mengurangi batas waktu panggilan sistem TCP connect ()?
sumber
telnet canyouseeme.org 81
juga hang. Ini dikendalikan oleh batas waktu habis Anda yang mungkin hardcoded di bash. Lihat: mengurangi batas waktu panggilan sistem TCP connect () .$SERVER
dan$PORT
dengan kawat gigi, setidaknya sebagai${SERVER}
dan${PORT}
.Saya membutuhkan solusi yang lebih fleksibel untuk mengerjakan beberapa repositori git jadi saya menulis kode sh berikut berdasarkan pada 1 dan 2 . Anda dapat menggunakan alamat server Anda alih-alih gitlab.com dan port Anda menggantikan 22.
sumber
Jika Anda menggunakan ksh atau bash, keduanya mendukung pengalihan IO ke / dari soket menggunakan konstruksi / dev / tcp / IP / PORT . Di shell Korn ini contoh saya mengarahkan no-op ( : ) std-in dari soket:
Shell mencetak kesalahan jika soket tidak terbuka:
Oleh karena itu Anda dapat menggunakan ini sebagai tes di jika kondisi :
No-op berada dalam subkulit sehingga saya dapat membuang std-err jika pengalihan std-in gagal.
Saya sering menggunakan / dev / tcp untuk memeriksa ketersediaan sumber daya melalui HTTP:
One-liner ini membuka file descriptor 9 untuk membaca dari dan menulis ke soket, mencetak GET HTTP ke soket dan digunakan
cat
untuk membaca dari soket.sumber
</dev/tcp/canyouseeme.org/80
dan kemudian</dev/tcp/canyouseeme.org/81
.Sementara pertanyaan lama, saya baru saja berurusan dengan varian itu, tetapi tidak ada solusi di sini yang berlaku, jadi saya menemukan yang lain, dan saya menambahkannya untuk anak cucu. Ya, saya tahu OP mengatakan mereka mengetahui opsi ini dan itu tidak cocok untuk mereka, tetapi bagi siapa pun yang mengikuti setelah itu mungkin terbukti bermanfaat.
Dalam kasus saya, saya ingin menguji ketersediaan
apt-cacher-ng
layanan lokal daridocker
build. Itu berarti sama sekali tidak ada yang dapat diinstal sebelum tes. Tidaknc
,nmap
,expect
,telnet
ataupython
.perl
Namun hadir, bersama dengan perpustakaan inti, jadi saya menggunakan ini:sumber
Dalam beberapa kasus di mana alat-alat seperti curl, telnet, nc o nmap tidak tersedia, Anda masih memiliki peluang dengan wget
sumber
periksa port menggunakan bash
Contoh
port 22 terbuka
Kode
sumber
Jika Anda ingin menggunakan
nc
tetapi tidak memiliki versi yang mendukung-z
, coba gunakan--send-only
:dan dengan batas waktu:
dan tanpa pencarian DNS jika itu IP:
Ini mengembalikan kode sebagai
-z
berdasarkan apakah dapat terhubung atau tidak.sumber
Saya menduga sudah terlambat untuk menjawab, dan ini mungkin bukan jawaban yang bagus, tapi begini ...
Bagaimana dengan meletakkannya di dalam loop sementara dengan timer di atasnya. Saya lebih menyukai Perl daripada Solaris, tetapi tergantung pada shell yang Anda gunakan, Anda harus bisa melakukan sesuatu seperti:
Dan kemudian tambahkan bendera di loop sementara, sehingga jika habis sebelum selesai, Anda dapat mengutip batas waktu sebagai alasan kegagalan.
Saya menduga bahwa telnet memiliki saklar batas waktu juga, tetapi hanya dari atas kepala saya, saya pikir di atas akan berfungsi.
sumber
Saya membutuhkan skrip pendek yang dijalankan di cron dan belum menghasilkan. Saya memecahkan masalah saya menggunakan nmap
Untuk menjalankannya, Anda harus menginstal nmap karena itu bukan paket bawaan yang diinstal.
sumber
nmap
Output grepable mungkin juga berguna-oG -
untuk mengirimkannya ke stdout. (grep akan membutuhkan sedikit modifikasi)Ini menggunakan telnet di belakang layar, dan tampaknya berfungsi dengan baik di mac / linux. Itu tidak menggunakan netcat karena perbedaan antara versi di linux / mac, dan ini berfungsi dengan instalasi mac default.
Contoh:
is_port_open.sh
sumber
Berdasarkan jawaban yang paling banyak dipilih, berikut adalah fungsi untuk menunggu dua port terbuka, dengan batas waktu juga. Perhatikan dua port yang terbuka, 8890 dan 1111, serta maks_attempts (1 per detik).
sumber
nmap-ncat untuk menguji port lokal yang belum digunakan
sumber