Saya memiliki minimal * nix tanpa kepala yang tidak memiliki utilitas baris perintah untuk mengunduh file (mis. Tidak ada ikal, wget, dll). Saya hanya punya bash.
Bagaimana saya bisa mengunduh file?
Idealnya, saya ingin solusi yang akan bekerja di berbagai * nix.
bash
command-line
web
Chris Snow
sumber
sumber
gawk
Jawaban:
Jika Anda memiliki bash 2.04 atau lebih baru dengan perangkat
/dev/tcp
pseudo diaktifkan, Anda dapat mengunduh file dari bash itu sendiri.Rekatkan kode berikut langsung ke bash shell (Anda tidak perlu menyimpan kode ke file untuk dieksekusi):
Kemudian Anda bisa menjalankannya dari shell sebagai berikut:
Sumber: Moreaki 's jawaban upgrade dan menginstal paket melalui baris perintah cygwin?
Pembaruan: sebagaimana disebutkan dalam komentar, pendekatan yang diuraikan di atas adalah sederhana:
read
wasiat tersebut akan menghapus backslash dan memimpin spasi putih.$line
kutip.sumber
while read
seperti itu sampah backslash dan spasi putih terkemuka dan Bash tidak bisa menangani byte NUL dengan sangat baik sehingga file biner keluar. Dan tanda kutip$line
akan glob ... Tak satu pun dari ini saya lihat disebutkan dalam jawaban.Gunakan lynx.
Ini cukup umum untuk sebagian besar Unix / Linux.
-dump: membuang file pertama ke stdout dan keluar
Atau netcat:
Atau telnet:
sumber
lynx -source
lebih dekat dengan wgetDiadaptasi dari jawaban Chris Snow Ini juga dapat menangani file transfer biner
Anda dapat menguji file biner seperti ini
sumber
cat
. Saya tidak yakin apakah itu curang (karena itu bukan murni shell), atau solusi yang bagus (karenacat
merupakan alat standar, setelah semua). Tapi @ 131, Anda mungkin ingin menambahkan catatan tentang mengapa ini bekerja lebih baik daripada solusi lain di sini.Mengambil " Bash saja dan tidak ada yang lain " dengan ketat, inilah satu adaptasi dari jawaban sebelumnya ( @ Chris's , @ 131's ) yang tidak memanggil utilitas eksternal apa pun (bahkan yang standar) tetapi juga berfungsi dengan file biner:
Gunakan dengan
download http://path/to/file > file
.Kami menangani byte NUL dengan
read -d ''
. Bunyinya sampai byte NUL, dan mengembalikan true jika menemukan satu, false jika tidak. Bash tidak dapat menangani byte NUL dalam string, jadi ketikaread
kembali dengan true, kami menambahkan byte NUL secara manual saat mencetak, dan ketika itu mengembalikan false, kita tahu tidak ada byte NUL lagi, dan ini harus menjadi bagian terakhir dari data .Diuji dengan Bash 4.4 pada file dengan NUL di tengah, dan berakhir di nol, satu atau dua NUL, dan juga dengan
wget
dancurl
binari dari Debian.wget
Biner 373 kB memerlukan waktu sekitar 5,7 detik untuk diunduh. Kecepatan sekitar 65 kB / dtk atau sedikit lebih dari 512 kb / dtk.Sebagai perbandingan, solusi kucing @ 131 selesai dalam waktu kurang dari 0,1 detik, atau hampir seratus kali lebih cepat. Tidak terlalu mengejutkan, sungguh.
Ini jelas konyol, karena tanpa menggunakan utilitas eksternal, tidak banyak yang bisa kita lakukan dengan file yang diunduh, bahkan membuatnya tidak dapat dieksekusi.
sumber
echo
danprintf
sebagai builtin (perlu builtinprintf
untuk mengimplementasikannyaprintf -v
)Jika Anda memiliki paket ini libwww-perl
Anda cukup menggunakan:
sumber
lynx
solusinya, karena Perl pasti lebih cenderung diinstal sebelumnya daripada Lynx.Gunakan unggah sebagai gantinya, melalui SSH dari mesin lokal Anda
Kotak "minimal tanpa kepala * nix" berarti Anda mungkin memasukkan SSH ke dalamnya. Jadi, Anda juga dapat menggunakan SSH untuk mengunggahnya . Yang secara fungsional setara dengan pengunduhan (paket perangkat lunak, dll.) Kecuali bila Anda ingin perintah pengunduhan disertakan dalam skrip pada server tanpa kepala Anda, tentu saja.
Seperti yang ditunjukkan dalam jawaban ini , Anda akan menjalankan yang berikut ini di mesin lokal Anda untuk menempatkan file di server tanpa kepala jarak jauh Anda:
Mengunggah lebih cepat melalui SSH dari mesin ketiga
Kerugian dari solusi di atas dibandingkan dengan mengunduh adalah kecepatan transfer yang lebih rendah, karena koneksi dengan mesin lokal Anda biasanya memiliki bandwidth yang jauh lebih sedikit daripada koneksi antara server tanpa kepala Anda dan server lain.
Untuk mengatasi itu, Anda tentu saja dapat menjalankan perintah di atas pada server lain dengan bandwidth yang layak. Untuk membuatnya lebih nyaman (menghindari login manual pada mesin ketiga), berikut adalah perintah untuk dijalankan pada mesin lokal Anda .
Agar aman, salin & tempel perintah itu termasuk karakter spasi terkemuka
' '
. Lihat penjelasan di bawah ini untuk alasannya.Penjelasan:
Perintah akan ssh ke mesin ketiga Anda
intermediate-host
, mulai mengunduh file ke sana melaluiwget
, dan mulai mengunggahnya ketarget-host
melalui SSH. Mengunduh dan mengunggah menggunakan bandwidth Andaintermediate-host
dan terjadi pada saat yang sama (karena setara dengan Bash pipe), sehingga kemajuan akan cepat.Saat menggunakan ini, Anda harus mengganti dua login server (
user@*-host
), kata sandi host target (yourpassword
), URL unduhan (http://example.com/…
) dan jalur output pada host target Anda (/path/to/output-file.zip
) dengan nilai sendiri yang sesuai.Untuk
-T -e none
opsi SSH saat menggunakannya untuk mentransfer file, lihat penjelasan terperinci ini .Perintah ini dimaksudkan untuk kasus di mana Anda tidak dapat menggunakan mekanisme otentikasi kunci publik SSH - itu masih terjadi dengan beberapa penyedia hosting bersama, terutama Host Eropa . Untuk tetap mengotomatiskan proses, kami bergantung
sshpass
untuk dapat memasok kata sandi dalam perintah. Itu perlusshpass
diinstal pada host perantara Anda (disudo apt-get install sshpass
bawah Ubuntu).Kami mencoba menggunakan
sshpass
dengan cara yang aman, tetapi masih tidak seaman mekanisme pubkey SSH (kataman sshpass
). Secara khusus, kami menyediakan kata sandi SSH bukan sebagai argumen baris perintah tetapi melalui file, yang digantikan oleh substitusi proses bash untuk memastikannya tidak pernah ada pada disk. Iniprintf
adalah built-in bash, memastikan bagian kode ini tidak muncul sebagai perintah terpisah dalamps
output karena itu akan mengekspos kata sandi [ sumber ]. Saya pikir penggunaansshpass
ini sama amannya dengansshpass -d<file-descriptor>
varian yang direkomendasikanman sshpass
, karena bash memetakannya secara internal ke/dev/fd/*
deskriptor file semacam itu. Dan itu tanpa menggunakan file temp [ sumber] Tapi tidak ada jaminan, mungkin saya mengabaikan sesuatu.Sekali lagi untuk membuat
sshpass
penggunaan aman, kita perlu mencegah perintah agar tidak direkam ke bash history di mesin lokal Anda. Untuk itu, seluruh perintah diawali dengan satu karakter spasi, yang memiliki efek ini.Bagian
-o StrictHostKeyChecking=no
mencegah perintah gagal jika itu tidak pernah terhubung ke host target. (Biasanya, SSH kemudian akan menunggu input pengguna untuk mengonfirmasi upaya koneksi. Kami tetap melanjutkannya.)sshpass
mengharapkan assh
atauscp
perintah sebagai argumen terakhirnya. Jadi kita harus menulis ulangwget -O - … | ssh …
perintah khas menjadi bentuk tanpa bash pipe, seperti yang dijelaskan di sini .sumber
Berdasarkan resep @Chris Snow. Saya membuat beberapa peningkatan:
Ini kode:
sumber
echo -en "GET ${PATH} HTTP/1.1\r\nHost: ${HOST}\r\n${tag}\r\n\r\n" >&3
,,${tag}
tidak ditentukan.tag
variabel yang disetel dengan benar, sekarang berfungsi dengan baik.