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:
$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
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:
$p = proc_open('bash',$desc,$pipes);
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:
$p=proc_open('bash && ssh user@host',$desc,$pipes);
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:
#!/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);
?>
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).