Saya memiliki sistem yang hanya bisa saya masuki di bawah nama pengguna (pengguna saya), tetapi saya harus menjalankan perintah sebagai pengguna lain (pengguna skrip). Sejauh ini, saya telah datang dengan yang berikut untuk menjalankan perintah yang saya butuhkan:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
Namun jika, ketika saya mencoba menjalankan perintah yang lebih kompleks, seperti [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
saya dengan cepat mendapat masalah dengan mengutip. Saya tidak yakin bagaimana saya bisa mengirimkan contoh perintah kompleks ini bash -c
, ketika \"
sudah membatasi batas-batas perintah yang saya lewati (dan jadi saya tidak tahu bagaimana cara mengutip / tmp / Direktori tertentu, yang mencakup spasi.
Apakah ada solusi umum yang memungkinkan saya untuk meloloskan perintah apa pun, tidak peduli seberapa kompleks / gila penawarannya, atau apakah ini semacam batasan yang telah saya capai? Apakah ada solusi lain yang mungkin dan mungkin lebih mudah dibaca?
Jawaban:
Trik yang saya gunakan kadang-kadang adalah menggunakan base64 untuk menyandikan perintah, dan mengirimnya ke bash di situs lain:
Ini akan menyandikan skrip, dengan koma, garis miring terbalik, tanda kutip dan variabel di dalam string yang aman, dan mengirimkannya ke server lain. (
-w0
diperlukan untuk menonaktifkan pembungkus baris, yang terjadi pada kolom 76 secara default). Di sisi lain,$(base64 -d)
akan memecahkan kode skrip dan mengumpankannya ke bash untuk dieksekusi.Saya tidak pernah mendapat masalah dengan itu, tidak peduli seberapa kompleks skrip itu. Memecahkan masalah dengan melarikan diri, karena Anda tidak perlu melarikan diri apa pun. Itu tidak membuat file pada host jarak jauh, dan Anda dapat menjalankan skrip yang sangat rumit dengan mudah.
sumber
ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash"
base64 script | ssh remotehost 'base64 -d | sudo bash'
akan cukup :)Lihat
-tt
opsi? Bacassh(1)
manualnya.Satu hal yang sering saya lakukan adalah menggunakan vim dan menggunakan
:!cat % | ssh -tt somemachine
triknya.sumber
:!cat % | (command)
bisa dilakukan seperti:w !(command)
atau:!(command) < %
.ssh -tt
menyebabkan ssh saya tidak berakhir setelah perintah tertentu dijalankan (menambahkanexit
pada akhirnya tidak membantu)Saya pikir solusi termudah terletak pada modifikasi dari komentar @ thanasisk.
Buat skrip,
scp
ke mesin, lalu jalankan.Miliki skrip
rm
itu sendiri di awal. Shell telah membuka file, sehingga telah dimuat, dan kemudian dapat dihapus tanpa masalah.Dengan melakukan hal-hal dalam urutan ini (
rm
pertama, hal-hal lain kedua) itu bahkan akan dihapus ketika gagal di beberapa titik.sumber
Anda dapat menggunakan
%q
penentu format denganprintf
untuk menjaga variabel yang keluar untuk Anda:printf -v
menulis output ke variabel (dalam hal ini,$cmd_str
). Saya pikir ini adalah cara paling sederhana untuk melakukannya. Tidak perlu mentransfer file atau menyandikan string perintah (sebanyak yang saya suka triknya).Berikut adalah contoh yang lebih kompleks yang menunjukkan bahwa itu berfungsi untuk hal-hal seperti tanda kurung siku dan ampersand juga:
Saya belum mengujinya
sudo
tetapi harus sesederhana:Jika mau, Anda dapat melewati satu langkah dan menghindari membuat variabel perantara:
Atau bahkan hanya menghindari membuat variabel sepenuhnya:
sumber
Inilah cara "benar" (sintaksis) untuk mengeksekusi sesuatu seperti ini di bash:
Untuk penjelasan menyeluruh tentang cara kerjanya, silakan lihat https://stackoverflow.com/a/21761956/111948
sumber
Apakah Anda sadar bahwa Anda dapat menggunakan
sudo
untuk memberikan Anda shell di mana Anda dapat menjalankan perintah sebagai pengguna yang dipilih?sumber
Anda dapat menentukan skrip pada mesin lokal Anda dan kemudian
cat
mengirimnya ke mesin jarak jauh:sumber
sudo -u scriptuser
? Apakah heredoc dapat digunakan mengingat saya perlu memiliki variabel dalam skrip yang akan saya piping ke mesin?echo "sudo `cat fileForSsh.txt`" | ssh ...
tetapi saya terus berusahasudo: sorry, you must have a tty to run sudo
./etc/sudoers
mengubah filessh -tq user@host "sudo bash -s" < test.sh
Sederhana dan mudah.
sumber
Jika Anda menggunakan Bash shell yang cukup modern, Anda bisa menempatkan perintah Anda dalam suatu fungsi dan mencetak fungsi itu sebagai string menggunakan
export -p -f function_name
. Hasil dari string itu kemudian dapat berisi perintah arbitrer yang tidak harus dijalankan sebagai root.Contoh menggunakan pipa dari jawaban saya di Unix.SE :
Contoh yang mengambil menyimpan file untuk pengguna login dan menginstal program root:
Jika Anda ingin menjalankan seluruh perintah menggunakan
sudo
, Anda bisa menggunakan ini:sumber
Inilah solusi jelek saya (tidak benar-benar diuji) untuk ini:
Tidak bisa Anda lakukan:
Langkah selanjutnya adalah membuat
betterssh
skrip yang sudah melakukan ini:sumber
Untuk Anda yang perlu memberikan parameter ke skrip, harus sebagai berikut:
sumber
Pertama, buat skrip lokal dan kemudian jalankan dari jarak jauh menggunakan perintah follow:
sumber