Problem z iterakcyjną obsługą sftp z poziomu php

0

Mam pewien problem z przerzucaniem plików na serwer, kod wygląda następująco:

	$archive="report-666";
	$ds=array(0=>array("pipe","r"),1=>array("pipe", "w"),2=>array("pipe","w"));
	$env=array();
	$cmd="sftp -i ./key.ssh -o \"StrictHostKeyChecking=no\" -o \"UserKnownHostsFile=/dev/null\" user@localhost 2>&1";
echo "cmd=$cmd\n";
	$process=proc_open($cmd,$ds,$pipes,'./',$env);
	if(is_resource($process))
	{
		$stdin=$pipes[0];
		$stdout=$pipes[1];
		$stderr=$pipes[2];
		sleep(30);
		fwrite($stdin,"binary\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fwrite($stdin,"cd upload\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fwrite($stdin,"mkdir $archive\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fwrite($stdin,"cd $archive\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fwrite($stdin,"mkdir master\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fwrite($stdin,"cd master\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		foreach($files as $add)
		{
			fwrite($stdin,"rm \"$add\"\n");
			sleep(10);
			echo "out: ".stream_get_contents($stdout);
			echo "err: ".stream_get_contents($stderr);
			fwrite($stdin,"put \"$add\"\n");
			sleep(10);
			echo "out: ".stream_get_contents($stdout);
			echo "err: ".stream_get_contents($stderr);
		}
		fwrite($stdin,"bye\n");
		sleep(10);
		echo "out: ".stream_get_contents($stdout);
		echo "err: ".stream_get_contents($stderr);
		fclose($stdout);
		fclose($stdin);
		fclose($stderr);
		$ret=proc_close($process);
		echo "ret=$ret\n";
	}

Jak widać podałem sleep(10); wszędzie ale czasami brakuje tego czasu, jednak nie chce wszędzie dawać 60 sek z wiadomych przyczyn.
Z tym że jak ręcznie robię to w sftp to tam gdzie jest sleep(10); wystarczy poczekać aż sftp wypisze sftp> .
Próbowałem to zorganizować czyli najpierw odczytać 5 znaków z $stdout (te sftp> ) ale niestety w żaden sposób się nie udało tego zrobić.
Próbowałem warianty:

  • fgets($stdout)
  • while(...) fgetc($stdout)
  • fread($stdout,5)

Nie mogę również użyć batch formy, ponieważ sftp przerywa batch po pierwszym błędzie, więc:
przy pierwszym ładowaniu padnie na fwrite($stdin,"rm \"$add\"\n"); (bo jeszcze go tam nie ma)
zaś przy kolejnych padnie na fwrite($stdin,"mkdir $archive\n"); (bo folder już istnieje)

Jakieś sugestie?

1

Już znalazłem rozwiązanie, jednak plik batch ale instrukcje które mają prawo dać błąd trzeba poprzedzić znakiem -, np
-mkdir master
jak folder już będzie to da komunikat ale nie przerwie batcha

0

Co chcesz osiągnąć? W sensie jaki problem rozwiązać?

0
.andy napisał(a):

Co chcesz osiągnąć? W sensie jaki problem rozwiązać?

Pierwotnym problemem był batch który się przerywał przy pierwszym napotkanym błędzie.
Więc postanowiłem że będę w trybie interaktywnym z sftp współpracować, zaś nie da się tego zrobić za pomocą php (lub ja nie umiem) - samo w sobie to ciekawe zagadnienie.
Z tym że przypadkiem napotkałem stronę gdzie napisano jak zrobić aby batch nie przerywał przy pierwszym napotkanym błędzie - tego mi wystarczyło aby ruszyć dalej,
Z tym że chętnie wypróbuję każdą sugestie związaną z interakcja z programem konsolowym z poziomu php.

0

@_13th_Dragon: nie zrozumiałeś 😋
Jaki problem chcesz tym rozwiązać? Z tego co dojrzałem na szybko, to wysyłasz jakoś pliki tak?

0

W tej chwili chcę osiągnąć interakcji, czyli jak proces wypisał sftp> to analizuje co sftp wypisał na stdout oraz stderr i w zależności od tego wysyłam kolejną komendę.
Chyba to proste, potrzebuje interakcji, piszę o tym w trzeciej odpowiedzi z rzędu?
Może to rozjaśni nieco moje pytanie: https://pl.wikipedia.org/wiki/Interakcja_(informatyka)

0

Dalej się nie rozumiemy.... Może spróbuję inaczej. Jaki problem ma rozwiązać to co stworzyłeś?
Chcesz poprzez sftp wysyłać raporty i odczytywać sobie czy się wysłały?

0

Nie chcę odczytywać, chcę wysłać aktualną wersję plików niezależnie czy jest już na serwerze aktualna wersja czy jakaś poprzednia czy w ogóle brak jakiejkolwiek.

0

@_13th_Dragon: dla mnie to wszystko przekombinowane. Nie lepiej np. użyć czegoś jak rsnapshot?

Dodam jeszcze, że u siebie na lapku używam Borga.
Można go skonfigurować aby kopie wysyłał po ssh.

0

Nie, bo do jednego folderu na ftp serwerze trzeba wrzucać pliki nawet z różnych dysków.

0

@_13th_Dragon: no to może goły rsync?

0
_13th_Dragon napisał(a):

Nie, bo do jednego folderu na ftp serwerze trzeba wrzucać pliki nawet z różnych dysków.

Jak z tym sobie poradzi goły rsync?
Również powiedziałem że admin zainstaluje cokolwiek w miesiąc w najlepszym przypadku, zaś działać ma w poniedziałek.
Poza tym przecież już powiedziałem wyraźnie że sprawa jest rozwiązana!

Jedyne co może jeszcze wnieść na przyszłość to jak zrobić interakcję z jakimkolwiek programem poprzez open_process.

1 użytkowników online, w tym zalogowanych: 0, gości: 1