dan saya diingatkan bahwa ssh tidak mengalokasikan pseudo-tty secara default. Kenapa tidak? Apa manfaat yang akan hilang jika saya tidak sshmau ssh -t?
> Saya diingatkan bahwa ssh tidak mengalokasikan psuedo-tty Apa yang terjadi? Itu akan memperkaya pertanyaan untuk memahami apa masalahnya.
Air
5
@ Air Tidak ada masalah yang saya coba perbaiki. Ada pilihan dalam bagaimana ssh diimplementasikan yang saya coba pahami. Pertanyaannya sangat jelas dan jawaban oleh Andrew B menjawab pertanyaan itu dengan baik. Jawabannya dapat diringkas seperti ini: menjalankan ssh -tselalu buruk karena dapat menyebabkan beberapa perintah rusak dengan cara yang aneh. Sedangkan, menjalankan perintah yang membutuhkan PTY tanpa satu menghasilkan pesan kesalahan yang jelas bahwa Anda memerlukan terminal.
Chas. Owens
Jawaban:
73
Perbedaan utama adalah konsep interaktivitas . Ini mirip dengan menjalankan perintah secara lokal di dalam skrip, vs. mengetiknya sendiri. Ini berbeda karena perintah jarak jauh harus memilih default, dan non-interaktif paling aman. (dan biasanya paling jujur)
STDIN
Jika PTY dialokasikan, aplikasi dapat mendeteksi ini dan tahu bahwa aman untuk meminta pengguna untuk input tambahan tanpa merusak barang-barang. Ada banyak program yang akan melewatkan langkah meminta pengguna untuk input jika tidak ada terminal, dan itu hal yang baik. Itu akan menyebabkan skrip hang yang tidak perlu jika tidak.
Input Anda akan dikirim ke server jarak jauh selama durasi perintah. Ini termasuk urutan kontrol. Sementara Ctrl-cistirahat biasanya akan menyebabkan perulangan pada perintah ssh untuk segera rusak, urutan kontrol Anda akan dikirim ke server jauh. Ini menghasilkan kebutuhan untuk "memalu" keystroke untuk memastikan bahwa itu tiba ketika kontrol meninggalkan perintah ssh, tetapi sebelum perintah ssh berikutnya dimulai.
Saya akan memperingatkan agar tidak menggunakan ssh -tskrip yang tidak dijaga, seperti crons. Shell non-interaktif yang meminta perintah jarak jauh untuk bertindak secara interaktif untuk input meminta semua jenis masalah.
Anda juga dapat menguji keberadaan terminal di skrip shell Anda sendiri. Untuk menguji STDIN dengan versi bash yang lebih baru:
# fd 0 is STDIN
[ -t 0 ]; echo $?
STDOUT
Ketika aliasing sshto ssh -t, Anda dapat mengharapkan untuk mendapatkan carriage return tambahan di jalur Anda. Mungkin tidak terlihat oleh Anda, tetapi ada di sana; itu akan muncul seperti ^Mketika disalurkan ke cat -e. Anda kemudian harus mengeluarkan upaya tambahan untuk memastikan bahwa kode kontrol ini tidak ditugaskan untuk variabel Anda, terutama jika Anda akan memasukkan output itu ke dalam database.
Ada juga risiko bahwa program akan menganggap mereka dapat membuat output yang tidak ramah untuk pengalihan file. Biasanya jika Anda mengarahkan ulang STDOUT ke file, program akan mengenali bahwa STDOUT Anda bukan terminal dan menghilangkan kode warna apa pun. Jika pengalihan STDOUT berasal dari output klien ssh dan ada PTY yang terkait dengan ujung jarak jauh klien, program jarak jauh tidak dapat membuat perbedaan seperti itu dan Anda akan berakhir dengan sampah terminal di file output Anda. Mengarahkan output ke file di ujung koneksi yang jauh harus tetap berfungsi seperti yang diharapkan.
Berikut ini adalah tes bash yang sama seperti sebelumnya, tetapi untuk STDOUT:
# fd 1 is STDOUT
[ -t 1 ]; echo $?
Meskipun mungkin untuk mengatasi masalah ini, Anda pasti akan lupa untuk merancang skrip di sekitar mereka. Kita semua melakukannya pada titik tertentu. Anggota tim Anda mungkin juga tidak menyadari / ingat bahwa alias ini sudah ada, yang pada gilirannya akan menimbulkan masalah bagi Anda ketika mereka menulis skrip yang menggunakan alias Anda.
Mengasingkan sshdiri ssh -tmerupakan kasus dimana Anda akan melanggar prinsip desain yang paling tidak mengejutkan ; orang akan menghadapi masalah yang tidak mereka harapkan dan mungkin tidak mengerti apa yang menyebabkannya.
Seseorang hampir mendapat kesan bahwa saya telah bekerja di tim yang telah melakukan ini ...
Andrew B
Pada ruang lingkup yang dicakup oleh jawaban ini, ini luar biasa. Tetapi pertanyaan itu memiliki ruang lingkup yang lebih luas, pada dasarnya ingin mengetahui SEMUA perbedaan (apa yang diharapkan). Info tambahan: Pada tingkat proses, -t akan PERTAMA mengalokasikan tty dan MAKA menjalankan shell (sepanjang jalan, sumber / etc / profile dan ~ / .bash_profile) dan KEMUDIAN jalankan perintah. Tanpa -t, ssh akan MENGINSTAL sumber file env yang berbeda (/etc/bash.bashrc, lalu ~ / .bashrc) dan MAKA menjalankan perintah Anda. Ini berarti Anda dapat melihat perilaku yang sangat berbeda di masing-masing: $ PATH lebih pendek, mungkin kesalahan 'unary' bash karena ENV var Anda berasumsi tidak ada ...
Scott Prive
@Crossfit Kami membahas topik shell login vs. non dalam komentar jawaban lain, tetapi kami tidak membahas secara mendalam perbedaan lingkungan karena OP telah mempertimbangkan pertanyaan yang dijawab untuk kebutuhan khusus mereka. Jangan ragu untuk menambahkan detail di mana Anda melihat ruang untuk melakukannya karena dapat membantu orang lain yang menemukan Q&A ini.
Andrew B
33
SSH melepaskan karakter dan mentransfer file biner
Salah satu keuntungan yang belum disebutkan dalam jawaban yang lain adalah bahwa ketika beroperasi tanpa pseudo-terminal , SSH yang melarikan diri karakter seperti ~Cyang tidak didukung ; ini membuatnya aman bagi program untuk mentransfer file biner yang mungkin mengandung urutan ini.
Ini sangat penting untuk program seperti scpatau rsyncyang menggunakan SSH untuk transfer data. Ini penjelasan rinci tentang bagaimana protokol SCP bekerja menjelaskan bagaimana protokol SCP terdiri dari campuran pesan protokol tekstual dan data file biner.
OpenSSH membantu melindungi Anda dari diri sendiri
Perlu dicatat bahwa meskipun -tflag digunakan, sshklien OpenSSH akan menolak untuk mengalokasikan pseudo-terminal jika mendeteksi bahwa stdinalirannya bukan terminal:
$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb
Anda masih dapat memaksa klien OpenSSH untuk mengalokasikan pseudo-terminal dengan -tt:
Bagus tapi hasilnya indentasi /: Apakah Anda tahu kalau Anda bisa mengembalikan otomatis (seperti unix)?
Boop
1
Pikirkan tentang kompatibilitas ke belakang.
2 mode utama ssh adalah login interaktif dengan tty, dan perintah khusus tanpa tty, karena itu adalah kemampuan yang tepat dari rlogindan rshmasing - masing. ssh diperlukan untuk menyediakan superset rlogin/ rshfitur agar berhasil sebagai pengganti.
Jadi defaultnya diputuskan sebelum ssh lahir. Kombinasi seperti "Saya ingin menentukan perintah dan mendapatkan tty" harus diakses dengan opsi baru. Bersyukurlah bahwa setidaknya kita memiliki opsi itu sekarang, tidak seperti ketika kita menggunakan rsh. Kami tidak menukar fitur yang berguna untuk mendapatkan koneksi terenkripsi. Kami mendapat fitur bonus!
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Ini memungkinkan Anda mendapatkan semacam "shell" ke server jarak jauh. Untuk server yang tidak memberikan akses shell tetapi mengizinkan SSH (yaitu, Github adalah contoh yang dikenal untuk akses SFTP), menggunakan flag ini akan menyebabkan server menolak koneksi Anda.
Shell juga memiliki semua variabel lingkungan Anda (seperti $PATH) sehingga mengeksekusi skrip umumnya membutuhkan tty untuk bekerja.
Ini tidak menjawab pertanyaan. Saya sudah tahu bagaimana cara mengalokasikan pseudo-tty. Saya ingin tahu mengapa saya tidak selalu mengalokasikannya.
Chas. Owens
1
@ Chas.Owens Karena, seperti yang saya tunjukkan dalam jawaban beberapa server SSH tidak mengizinkan akses tty dan itu akan menjatuhkan koneksi jika Anda meminta satu dari server.
Nathan C
5
Saya pikir Anda mungkin membuat beberapa terminologi Anda bingung. Ini bukan shell hanya karena PTY dikaitkan dengannya. Pada umumnya ada tiga jenis shell: non-interactive, interactive, dan login. loginadalah karakteristik tambahan dari dua jenis shell lainnya. Permutasi dari ketiga menentukan file mana yang bersumber pada login, yang pada gilirannya mempengaruhi bagaimana lingkungan akan diinisialisasi. (variabel, seperti yang Anda sebutkan)
Andrew B
3
@AndrewB Anda benar ... Saya belajar sesuatu dari pertanyaan ini juga. :)
ssh -t
selalu buruk karena dapat menyebabkan beberapa perintah rusak dengan cara yang aneh. Sedangkan, menjalankan perintah yang membutuhkan PTY tanpa satu menghasilkan pesan kesalahan yang jelas bahwa Anda memerlukan terminal.Jawaban:
Perbedaan utama adalah konsep interaktivitas . Ini mirip dengan menjalankan perintah secara lokal di dalam skrip, vs. mengetiknya sendiri. Ini berbeda karena perintah jarak jauh harus memilih default, dan non-interaktif paling aman. (dan biasanya paling jujur)
STDIN
Ctrl-c
istirahat biasanya akan menyebabkan perulangan pada perintah ssh untuk segera rusak, urutan kontrol Anda akan dikirim ke server jauh. Ini menghasilkan kebutuhan untuk "memalu" keystroke untuk memastikan bahwa itu tiba ketika kontrol meninggalkan perintah ssh, tetapi sebelum perintah ssh berikutnya dimulai.Saya akan memperingatkan agar tidak menggunakan
ssh -t
skrip yang tidak dijaga, seperti crons. Shell non-interaktif yang meminta perintah jarak jauh untuk bertindak secara interaktif untuk input meminta semua jenis masalah.Anda juga dapat menguji keberadaan terminal di skrip shell Anda sendiri. Untuk menguji STDIN dengan versi bash yang lebih baru:
STDOUT
ssh
tossh -t
, Anda dapat mengharapkan untuk mendapatkan carriage return tambahan di jalur Anda. Mungkin tidak terlihat oleh Anda, tetapi ada di sana; itu akan muncul seperti^M
ketika disalurkan kecat -e
. Anda kemudian harus mengeluarkan upaya tambahan untuk memastikan bahwa kode kontrol ini tidak ditugaskan untuk variabel Anda, terutama jika Anda akan memasukkan output itu ke dalam database.Berikut ini adalah tes bash yang sama seperti sebelumnya, tetapi untuk STDOUT:
Meskipun mungkin untuk mengatasi masalah ini, Anda pasti akan lupa untuk merancang skrip di sekitar mereka. Kita semua melakukannya pada titik tertentu. Anggota tim Anda mungkin juga tidak menyadari / ingat bahwa alias ini sudah ada, yang pada gilirannya akan menimbulkan masalah bagi Anda ketika mereka menulis skrip yang menggunakan alias Anda.
Mengasingkan
ssh
dirissh -t
merupakan kasus dimana Anda akan melanggar prinsip desain yang paling tidak mengejutkan ; orang akan menghadapi masalah yang tidak mereka harapkan dan mungkin tidak mengerti apa yang menyebabkannya.sumber
SSH melepaskan karakter dan mentransfer file biner
Salah satu keuntungan yang belum disebutkan dalam jawaban yang lain adalah bahwa ketika beroperasi tanpa pseudo-terminal , SSH yang melarikan diri karakter seperti
~C
yang tidak didukung ; ini membuatnya aman bagi program untuk mentransfer file biner yang mungkin mengandung urutan ini.Bukti dari konsep
Salin file biner menggunakan terminal semu:
Salin file biner tanpa menggunakan pseudo-terminal:
Kedua file tidak sama:
Yang disalin dengan terminal semu rusak:
sementara yang lain tidak:
Mentransfer file melalui SSH
Ini sangat penting untuk program seperti
scp
ataursync
yang menggunakan SSH untuk transfer data. Ini penjelasan rinci tentang bagaimana protokol SCP bekerja menjelaskan bagaimana protokol SCP terdiri dari campuran pesan protokol tekstual dan data file biner.OpenSSH membantu melindungi Anda dari diri sendiri
Perlu dicatat bahwa meskipun
-t
flag digunakan,ssh
klien OpenSSH akan menolak untuk mengalokasikan pseudo-terminal jika mendeteksi bahwastdin
alirannya bukan terminal:Anda masih dapat memaksa klien OpenSSH untuk mengalokasikan pseudo-terminal dengan
-tt
:Dalam kedua kasus, itu (masuk akal) tidak peduli jika
stdout
ataustderr
diarahkan:sumber
Pada host jarak jauh kita harus lakukan dengan pengaturan ini:
Tanpa sudo
Dan dengan sudo
Dengan sudo kita mendapatkan kereta ekstra
Solusinya adalah dengan menonaktifkan terjemahan baris baru ke carriage return-newline with
stty -onlcr
sumber
Pikirkan tentang kompatibilitas ke belakang.
2 mode utama ssh adalah login interaktif dengan tty, dan perintah khusus tanpa tty, karena itu adalah kemampuan yang tepat dari
rlogin
danrsh
masing - masing. ssh diperlukan untuk menyediakan supersetrlogin
/rsh
fitur agar berhasil sebagai pengganti.Jadi defaultnya diputuskan sebelum ssh lahir. Kombinasi seperti "Saya ingin menentukan perintah dan mendapatkan tty" harus diakses dengan opsi baru. Bersyukurlah bahwa setidaknya kita memiliki opsi itu sekarang, tidak seperti ketika kita menggunakan
rsh
. Kami tidak menukar fitur yang berguna untuk mendapatkan koneksi terenkripsi. Kami mendapat fitur bonus!sumber
Dari
man ssh
:Ini memungkinkan Anda mendapatkan semacam "shell" ke server jarak jauh. Untuk server yang tidak memberikan akses shell tetapi mengizinkan SSH (yaitu, Github adalah contoh yang dikenal untuk akses SFTP), menggunakan flag ini akan menyebabkan server menolak koneksi Anda.
Shell juga memiliki semua variabel lingkungan Anda (seperti
$PATH
) sehingga mengeksekusi skrip umumnya membutuhkan tty untuk bekerja.sumber
non-interactive
,interactive
, danlogin
.login
adalah karakteristik tambahan dari dua jenis shell lainnya. Permutasi dari ketiga menentukan file mana yang bersumber pada login, yang pada gilirannya mempengaruhi bagaimana lingkungan akan diinisialisasi. (variabel, seperti yang Anda sebutkan)