interakcja proc_open
Oto, co próbuję osiągnąć: otwórz powłokę (korn lub bash, nie ma znaczenia), z tej powłoki chcę otworzyć połączenie ssh (ssh user@host
). W pewnym momencie może się zdarzyć, że zostaniesz poproszony o podanie hasła lub zostaniesz zapytany, czy na pewno chcę się połączyć (obrażając klucze).
Zanim ktokolwiek zapyta: tak, zdaję sobie sprawę, że istnieje wtyczka do wywołań ssh2 exec, ale serwery, na których pracuję, nie obsługują tego i nie jest to możliwe.
Oto, co próbowałem do tej pory:
<code>$desc = array(array('pipe','r'),array('pipe','w'));//used in all example code $p = proc_open('ssh user@host',$desc,$pipes); if(!is_resource($p)){ die('@!#$%');}//will omit this line from now on sleep(1);//omitting this,too but it's there every time I need it </code>
Następnie próbowałem odczytać dane wyjściowe konsoli (stream_get_contents($pipes[1])
) aby zobaczyć, co mam przejść dalej (hasło, tak lub wróć)'connection failed: '.stream_get_contents($pipes[1])
i proc_close $ p.
Dało mi to następujący błąd:
Pseudo-terminal nie zostanie przydzielony, ponieważ stdin nie jest terminalem.
Tak więc, chociaż ssh został wywołany wphp://
kontekst ja-stream, wydaje się prawdopodobnym wyjaśnieniem powyższego błędu.
Dalej: myślałem omoje pierwsze pytanie SO i zdecydowałem, że dobrym pomysłem może być najpierw otwarcie powłoki bash / ksh:
<code>$p = proc_open('bash',$desc,$pipes); </code>
I zabierz go stamtąd, ale otrzymałem dokładnie ten sam komunikat o błędzie, tylko tym razem skrypt przestał działać, ale ssh działał. Więc miałem nadzieję, a potem poczułem się głupio iw końcu zrozpaczony:
<code>$p=proc_open('bash && ssh user@host',$desc,$pipes); </code>
Po kilku sekundach czeka mnie następujący błąd:
Błąd PHP Fatal: Dozwolona wielkość pamięci 134217728 bajtów wyczerpana (próbowano przydzielić 133693440 bajtów)
Call Stack ciągle podnosi linię stream_get_contents, nawet w mojej ostatniej desperackiej próbie:
<code>#!/path/to/bin/php -n <?php $p = proc_open('bash && ssh user@host',array(array('pipe','r'),array('pipe','w')),$ps); if (!is_resource($p)) { die('FFS'); } usleep(10); fwrite($ps[0],'yes'."\n"); fflush($ps[0]); usleep(20); fwrite($ps[0],'password'."\n"); fflush($ps[0]); usleep(20); fwrite($ps[0],'whoami'."\n"); fflush($ps[0]); usleep(2); $msg = stream_get_contents($ps[1]); fwrite($ps[0],'exit'."\n"); fclose($ps[0]); fclose($ps[1]); proc_close($p); ?> </code>
Wiem, to bałagan, dużofflush
i nadmiarowość, ale chodzi o to, że wiem, że to połączenie najpierw poprosi mnie o obrażenie kluczy, a następnie poprosi o hasło. Domyślam się, że strumień w $ pipes [1] zawiera połączenie ssh, stąd jego zawartość jest ogromna. to, czego potrzebuję, to rura w rurze ... czy to jest możliwe? Musi mi brakować czegoś, co jest fajką, jeśli nie jest to możliwe ... Domyślam się, że polecenie proc_open jest błędne na początku (błąd: Przerwana rura). Ale naprawdę nie widzę innego sposobu obejścia pierwszego błędu ... żadnych myśli? Możesz też zadawać pytania, jeśli powyższy argument nie jest wcale jasny (co prawdopodobnie nie jest).