piątek, 26 czerwca 2009

Zdalny pipe

Dziś kolega 'junior admin' podniecił się strasznie możliwością przekierowywania standardowego wyjścia programu na standardowe wejście kolejnego między lokalnym i zdalnym systemem, czyli tzw. pipem. Zacznijmy od dwóch przykładów, które mi podesłał:
tar cf - whatever | ssh remotehost " ( cd /some/path ; tar xf - ) "
ssh remotehost "( cd /somewhere ; tar cf - something ) " | tar xf -
W pierwszej linijce pakujemy (bez kompresji) zadaną jako drugi parametr listę plików, pierwszym parametrem jest w tym wypadku znak '-' często używany jeśli chcemy uzyskać coś na STDOUT zamiast zapisać gdzieś w pliku, gdy program to umożliwia. Tak więc znak '-' informuje polecenie tar, że zamiast zapisywać tworzone archiwum do pliku ma wyrzucić wynik na standardowe wyjście (czyli w linuksie plik o deskryptorze 1).
Następnie mamy | czyli przekierowanie/przekazanie standardowego wyjścia poprzednio wykonywanej komendy (opisanej już jedyneczki) na standardowe wejście kolejnej komendy (STDIN - czyli deskryptor pliku o identyfikatorze 0 [zero])
Kolejnym poleceniem jest wywołanie ssh - nawiąż połączenie z hostem remotehost i wykonaj polecenia podane jako kolejny parametr. Podajemy je w cudzysłowiu, żeby bash w trakcie przetwarzania nie potraktował spacji jako separatora kolejnych argumentów (pewnie poleciałyby błedy - można spróbować - na pewno coś 'chorego' się stanie. O interpretacji linii poleceń przez shell to może innym razem - jak ktoś z czytelników będzie bardzo tego chciał).
Pozostaje więc ostatnia część:
cd /some/path ; tar xf -
To już dosyć proste - zmieniamy ścieżkę i rozpakowujemy archiwum poleceniem tar (x - extract). Pojawia się znowu magiczny minus. W wypadku rozpakowywania (jak co poniektórzy pewnie się domyślają) minus mówi o tym, że źródłem z którego należy czytać nie jest plik a standardowe wejście (przytaczane wcześniej zero).

Drugi przypadek pozostawiam do samodzielnej analizy. W razie problemów i pytań służę pomocą

Do samodzielnej lektury polecam wikipedię
Co mi tu jeszcze ciekawego przyszło do głowy. Każdy program po wykonaniu zwraca status wykonania w postaci liczbowej. Znajdziemy go w zmiennej shella $?:
echo $?
Jeżeli program wykonał się poprawnie - nie pojawiły się błędy - to status powinien być równy 0 [zero]. W przypadku problemów będzie to cyfra różna od zero - to co będzie oznaczać zależy już od programu. Warto sprawdzać tą zmienną pisząc skrypty - przez co możemy przerwać je w odpowiednim momencie, gdy coś pójdzie nie tak a nie zostawić wszystko dalszemu biegowi wypadków.
A co w wypadku gdy łączymy kilka poleceń w pipe? Jak wykryć, że któreś (nieostatnie) polecenie wykonało się niepoprawnie?

Odpowiedź w przyszłym blogu...
Może warto poszukać samemu?

Czekam na komentarze...

Brak komentarzy:

Prześlij komentarz