Widziałem pytania i odpowiedzi dotyczące konieczności podwójnego ucieczki argumentów do zdalnych poleceń ssh. Moje pytanie brzmi: dokładnie gdzie i kiedy wykonuje się drugie parsowanie?
Jeśli uruchomię następujące:
$ ssh otherhost pstree -a -p
W danych wyjściowych widzę następujące:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
Proces nadrzędny dla polecenia zdalnego ( pstree
) polega na tym sshd
, że nie wydaje się, aby istniała tam jakaś powłoka, która analizowałaby argumenty wiersza poleceń dla polecenia zdalnego, więc nie wydaje się, że konieczne byłoby podwójne cytowanie lub zmiana znaczenia ( ale na pewno jest). Jeśli zamiast tego najpierw ssh tam i uzyskać powłokę logowania, a następnie uruchomić pstree -a -p
widzę następujące dane wyjściowe:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Widać więc, że istnieje tam bash
powłoka, która w takim przypadku przeprowadzałaby analizę wiersza poleceń. Ale w przypadku, gdy używam polecenia zdalnego bezpośrednio, wydaje się, że nie ma powłoki, więc dlaczego podwójne cytowanie jest konieczne?
Myślę, że wymyśliłem to:
Argumenty, które
pstree
należy wykonać: pokazać argumenty wiersza poleceń, pokazać pidy i pokazać tylko procesy nadrzędne danego pid.'$$'
Jest specjalną zmienną powłoki bash, które zastąpi z własnym PID kiedy bash ocenia argumenty wiersza poleceń. Jest cytowany raz, aby powstrzymać go przed interpretacją przez moją lokalną powłokę. Ale nie jest podwójnie cytowany ani nie ma znaczenia, aby umożliwić interpretację go przez zdalną powłokę.Jak widzimy, jest on zastąpiony przez,
12001
więc jest to pid powłoki. Na podstawie danych wyjściowych widzimy również,pstree,12001
że sam proces z pid 12001 jest pstree. Więcpstree
jest skorupa?To, co zbieram, dzieje się tam, że
bash
jest wywoływane i analizuje argumenty wiersza poleceń, ale następnie wywołuje się wexec
celu zastąpienia się uruchamianym poleceniem.Wygląda na to, że robi to tylko w przypadku pojedynczego polecenia zdalnego:
W takim przypadku żądam uruchomienia dwóch poleceń:
pstree
następnieecho
. Widzimy tutaj, żebash
tak naprawdę pojawia się w drzewie procesów jako rodzicpstree
.źródło
Wspierając to, co powiedziały inne odpowiedzi, poszukałem kodu wywołującego polecenia na pilocie, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...
... które, jak widać, bezwarunkowo przywołuje
shell
pierwszy argument-c
i drugi argumentcommand
. Wcześniejshell
zmienna była ustawiona na powłokę logowania użytkownika, jak zapisano w/etc/passwd
.command
jest argumentem tej funkcji i ostatecznie jest ustawiony na ciąg odczytywany dosłownie z drutu (patrzsession_exec_req
w tym samym pliku ). Tak więc serwer w ogóle nie interpretuje polecenia, ale na pilocie zawsze wywoływana jest powłoka.Jednak odpowiednia część specyfikacji protokołu SSH czy nie wydaje się wymagać tego zachowania; mówi tylko
Jest to prawdopodobnie spowodowane tym, że nie wszystkie systemy operacyjne mają koncepcję powłoki wiersza poleceń. Na przykład nie byłoby szaleństwem, gdyby serwer ssh Classic MacOS podawał ciągi poleceń „exec” do interpretera AppleScript .
źródło