Dengan ssh, bagaimana Anda bisa menjalankan perintah pada mesin jarak jauh tanpa keluar?

29

Biasanya, jika Anda memberikan perintah ke ssh seperti itu

ssh [email protected] 'some-command.sh'

Anda mendapatkan sesi non-interaktif, dan ssh keluar segera setelah perintah (atau skrip, atau apa pun) dijalankan. Bagaimana saya bisa mendapatkan sesi interaktif, dan belum menjalankan perintah yang saya tentukan dari mesin lokal saya. Misalnya, saya ingin dapat membuka layar dan memulai kembali sesi layar tertentu:

ssh [email protected] 'screen -r 12345'

tetapi ini tidak diperbolehkan, mengembalikan kesalahan "Harus terhubung ke terminal." yang saya anggap berarti pada dasarnya "harus memanggil perintah ini dari shell interaktif".

Sebagai contoh lain, saya menggunakan banyak mesin di tempat kerja yang sering mengharuskan saya untuk menggunakan akun bersama untuk memiliki hak untuk melakukan hal-hal tertentu (ya saya tahu: ide buruk tapi jangan salahkan saya, saya tidak mengatur hal-hal yang cara), dan mereka biasanya memiliki ksh sebagai shell default. Saya ingin masuk, beralih ke bash (atau zsh), dan sumber .bash_profile (atau .zshrc) akun saya sendiri. Ini akan mudah jika saya bisa membuat sesi ssh interaktif dan meneruskan perintah ke mesin jarak jauh untuk dijalankan saat login.

Saya memiliki solusi yang sangat kludgey (dan belum diuji) dalam pikiran bahwa saya akan memposting, tetapi saya berharap seseorang tahu cara yang lebih baik.

PEMBARUAN: bagi mereka yang tidak menyadari hal ini, saya tidak berencana untuk melakukan semua ini dengan tangan, jadi menyuruh saya untuk membuka sesi interaktif dan kemudian melakukannya dengan tangan tidak benar-benar menyelesaikan apa pun.

PEMBARUAN KE-2: Mencoba sekali lagi untuk mengklarifikasi: Saya mencoba menjalankan perintah (sewenang-wenang) di server (ditentukan secara program pada klien) tetapi kemudian memiliki sesi interaktif terbuka yang dipengaruhi oleh apa pun yang dilakukan oleh perintah-perintah program tersebut.

iconoclast
sumber
echo "command" | ssh user@remote_host
laggingreflex
2
Apakah Anda melewatkan bagian "tanpa keluar" dari pertanyaan? Saya cukup yakin ini akan keluar setelah perintah selesai.
iconoclast

Jawaban:

26

Anda dapat mencoba perintah berikut untuk memulai bash dan sumber profil Anda sendiri ketika Anda ssh:

ssh  -t hostname "bash --rcfile ~user/.bashrc"
dogbane
sumber
4
+1. The -tsaklar perbaikan masalah kuesioner dengan screenjuga.
Tambalan
3
Apakah ini dapat digunakan dengan perintah sewenang-wenang, tanpa menutup koneksi? Jika saya mencoba ssh -t www.dev "echo 'hi there'", koneksi langsung ditutup setelah perintah dijalankan.
iconoclast
11

Membangun berdasarkan jawaban dogbane, solusi lengkap terlihat seperti:

ssh -t user@server 'cd /a/great/place; bash'

Di sini saya gunakan -tuntuk memaksa alokasi pseudo-terminal, yang diperlukan untuk shell interaktif. Lalu saya menjalankan dua perintah di server: pertama hal yang ingin saya lakukan sebelum membuka shell interaktif (dalam kasus saya, mengubah direktori ke folder tertentu), dan kemudian shell interaktif itu sendiri. bash melihat bahwa ia memiliki terminal semu dan merespons secara interaktif.

Kutipan tunggal memastikan semuanya diteruskan ke server jauh sebagai perintah untuk dijalankan oleh shell default Anda.

Sekali lagi terima kasih kepada dogbane untuk memberikan petunjuk yang diperlukan -t. Saya biasa memecahkan masalah ini dengan expect, yang pasti membunuh tikus dengan meriam. (:

pengguna1179239
sumber
2

Coba solusi ini.

echo "command" | ssh user@remote_host

Login bersifat interaktif dan perintah Anda diteruskan seolah-olah Anda mengetiknya di baris perintah interaktif. Sesi berakhir seolah-olah Anda telah mengetik

ssh user@remote_host 'command'
pengguna210540
sumber
3
Jika sesi berakhir setelah perintah selesai, maka ini tidak menjawab pertanyaan. Seluruh inti dari perintah harus dibiarkan dengan sesi interaktif setelah perintah dieksekusi, bukan hanya untuk mengirim perintah ke server melalui ssh.
iconoclast
Ini setidaknya baik untuk mensimulasikan interaksi untuk perintah untuk dijalankan, tanpa menggunakan -tatau file bash Anda sendiri. +1
laggingreflex
0

Gunakan ssh -X untuk menggunakan termIO cmds.

Juga - Anda dapat mengaitkan cmds Anda seperti "ssh 'source ~ / .bashrc && cd && do'"

ethrbunny
sumber
tetapi setelah seluruh rantai selesai, saya tidak memiliki sesi interaktif yang tersisa, kan? Masih tertutup, kan?
iconoclast
Dan apakah Anda ingin menguraikan solusi termIO?
iconoclast
0

mengapa tidak menginstal detach pada sistem jarak jauh dan gunakan:

ssh -t [email protected] "/home/user/bin/detach ls"
Dan D.
sumber
akankah ini berjalan 'ls' dan MAKA meninggalkan saya dengan sesi interaktif? Bagaimana jika, alih-alih 'ls', saya menjalankan 'source .sfile' untuk mendapatkan beberapa alias dan fungsi. Apakah mereka akan tersedia di sesi interaktif saya, atau akankah itu dijalankan di bawah sesi yang berbeda?
iconoclast
Tidak, karena detach, lstidak membuat sesi terbuka dan akan memutuskan sambungan tanpa mencetak output dari lstetapi tetap berjalan.
Dan D.
Saya mencoba menjalankan (sewenang-wenang) perintah di server (ditentukan secara program pada klien) tetapi kemudian memiliki sesi interaktif terbuka yang dipengaruhi oleh apa pun yang dilakukan oleh perintah-perintah program tersebut. Jadi jika saya mengerti Anda dengan benar, ini tidak membantu saya.
iconoclast
0

jawaban laggingreflex sudah dekat ... Saya akan mengubahnya sebagai berikut:

echo "command\n$(cat -)" | ssh user@remote_host

Sayangnya, Anda tidak akan menyukai cara kerjanya, karena "cat" mendukung garis yang ditulisnya menjadi stdout ... Jika kita membuat skrip yang disebut "echo-cat" yang terlihat seperti ini:

{
  echo "${@}"
 #cat buffers & won't flush to stdout immediately
 #cat -
  IFS='\n'
  while read line
  do
        echo "${line}"
  done
}

kami akan mendapatkan hasil yang sama tanpa buffering:

echo-cat "command" | ssh user@remote_host

Itu mungkin akan membuat Anda lebih dekat ke tujuan Anda ...

Tagihan
sumber
0

Ini kludgey, dan belum teruji, tetapi saya pikir itu harus berhasil.

Buat skrip bernama (misalnya) remote-starter yang mengambil argumen yang dikutip setelah argumen pengguna @ host:

remote-starter [email protected] 'some-command.sh arg1 arg2'

Skrip ini pertama-tama harus menyimpan perintah yang dikutip (tanpa tanda kutip) dalam file bernama (misalnya) .onetimepada mesin remote, dan kemudian jalankan perintah ssh biasa, kali ini tidak melewati perintah apa pun untuk dijalankan di mesin jarak jauh. (Jika menjalankan ssh [email protected] dari dalam skrip, mungkin berfungsi untuk menjalankan exec ssh [email protected].)

Agar ini berfungsi, mesin remote harus sumber .onetimedari .bash_profile atau .zshrc atau apa pun. Setelah berjalan .onetime, seharusnya dihapus .onetime, sehingga file tidak berjalan saat Anda melakukan login reguler.

iconoclast
sumber