Saya telah melihat pertanyaan dan jawaban tentang perlunya meloloskan diri dari argumen ke perintah ssh jarak jauh. Pertanyaan saya adalah: Di mana dan kapan parsing kedua dilakukan?
Jika saya menjalankan yang berikut ini:
$ ssh otherhost pstree -a -p
Saya melihat yang berikut di output:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
Proses induk untuk perintah jarak jauh ( pstree
) adalah sshd
, tampaknya tidak ada shell di sana yang akan mem-parsing argumen baris perintah ke perintah jarak jauh, sehingga sepertinya tidak perlu kutip ganda atau melarikan diri ( tapi itu pasti). Jika sebaliknya saya ssh di sana terlebih dahulu dan mendapatkan shell login, lalu jalankan pstree -a -p
saya melihat yang berikut di output:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Jadi jelas ada bash
shell di sana yang akan melakukan parsing baris perintah dalam kasus itu. Tetapi kasus di mana saya menggunakan perintah jarak jauh secara langsung, sepertinya tidak ada shell, jadi mengapa pengutipan ganda diperlukan?
Saya pikir saya sudah menemukan jawabannya:
Argumen untuk
pstree
adalah: menunjukkan argumen baris perintah, menunjukkan pids, dan menunjukkan hanya proses induk dari pid yang diberikan. Ini'$$'
adalah variabel shell khusus yang akan diganti bash dengan pidnya sendiri ketika bash mengevaluasi argumen baris perintah. Ini dikutip sekali untuk menghentikannya agar tidak ditafsirkan oleh shell lokal saya. Tapi itu tidak dikutip atau melarikan diri ganda untuk memungkinkannya untuk ditafsirkan oleh shell jarak jauh.Seperti yang bisa kita lihat, itu diganti dengan
12001
begitu itu pid dari shell. Kita juga dapat melihat dari output:pstree,12001
bahwa proses dengan pid 12001 adalah pstree itu sendiri. Jadi,pstree
apakah cangkangnya?Apa yang saya kumpulkan sedang terjadi di sana adalah yang
bash
sedang dipanggil dan itu menguraikan argumen baris perintah, tetapi kemudian dipanggilexec
untuk mengganti sendiri dengan perintah yang sedang dijalankan.Tampaknya hanya melakukan ini dalam kasus perintah jarak jauh tunggal:
Dalam hal ini, saya meminta dua perintah dijalankan:
pstree
diikuti olehecho
. Dan kita dapat melihat di sini bahwabash
sebenarnya muncul di pohon proses sebagai indukpstree
.sumber
Mendukung apa yang dikatakan jawaban lain, saya mencari kode yang memanggil perintah pada remote, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...
... yang, seperti yang Anda lihat, secara tanpa syarat dipanggil
shell
dengan argumen pertama-c
dan argumen keduacommand
. Sebelumnya,shell
variabel diatur ke shell login pengguna sebagaimana dicatat dalam/etc/passwd
.command
adalah argumen untuk fungsi ini, dan pada akhirnya diatur ke string membaca kata demi kata dari kawat (lihatsession_exec_req
di file yang sama ). Jadi, server tidak menafsirkan perintah sama sekali, tetapi sebuah shell selalu dipanggil pada remote.Namun, bagian yang relevan dari spesifikasi protokol SSH tidak tidak muncul untuk meminta perilaku ini; hanya dikatakan
Ini mungkin karena tidak semua sistem operasi memiliki konsep shell command-line. Sebagai contoh, itu tidak akan gila untuk server ssh Classic MacOS untuk memberi makan string perintah "exec" ke juru bahasa AppleScript sebagai gantinya.
sumber