2011-02-02 17 views
6

Chcę przesłać niektóre dane do procesu root z nazwaną potokiem. Oto skrypt i działa świetnie:Skrypt Bash z nieblokującym odczytem

#!/bin/sh 
pipe=/tmp/ntp 

if [[ ! -p $pipe ]]; then 
    mknod -m 666 $pipe p 
fi 

while true 
do 
    if read line <$pipe; then 
     /root/netman/extra/bin/ntpclient -s -h $line > $pipe 2>&1 
    fi 
done 

Tak naprawdę mam kilka takich skryptów. Chciałbym zamknąć je wszystkie w jednym skrypcie. Problem polega na tym, że wykonanie blokuje pierwszy "odczyt" i nie mogę wykonać wielu "odczytów" w jednym procesie. Czy nie mogę nic zrobić? Czy możliwe jest odczytanie "nieblokującego" basha?

+0

Dlaczego chcesz połączyć oddzielne operacje w jedną całość? scenariusz? Jeśli każdy z nich działa poprawnie, pozostań niezależny. Jest to znacznie łatwiejsze niż próba naginania powłoki w nie blokujące czytania. Procesy są tanie. Proste procesy są również bezpieczniejsze niż złożone, a procesy root muszą być bezpieczne. –

+0

Zgodziłbym się z tobą, ale każdy proces zjada 628K pamięci RAM (jest to kopia basha) i jestem w środowisku osadzonym. Wolałbym zaoszczędzić jak najwięcej pamięci. – michelemarcon

+0

Jeśli to taki problem, napisz kod w C. –

Odpowiedz

3

Wystarczy umieścić cykl czytania w tle (dodać & po done)?

+0

Świetnie! Zmniejszyłem o połowę zużycie pamięci! – michelemarcon

+0

@michelemarcon: czy jesteś pewien, że oszczędzasz pamięć? Kiedy go przetestowałem, dodanie '&' zmusiło wykonanie pętli while w powłoce = inny proces = więcej pamięci. –

+0

Testowane za pomocą ps, każdy skrypt zjada 628K. W "&" każdy proces zjada 240K. I BTW, ponieważ każda "chwila" jest w tle, skrypt "matka" wychodził i zwalniał swoją pamięć – michelemarcon

0

Możesz użyć stty, aby ustawić limit czasu. IIRC jej coś

stty -F $pipe -icanon time 0 
+0

Otrzymuję niepoprawny argument. Ale prawdopodobnie jest tak dlatego, że pracuję z busybox [http://en.wikipedia.org/wiki/Busybox] – michelemarcon

+0

@michelemarcon Otrzymuję to samo i nie korzystam obecnie z busybox. Ale kiedy jestem, znalazłem tę stronę, która jest niezwykle przydatna: http://www.busybox.net/BusyBox.html –

+0

Otrzymuję również nieprawidłowy błąd argumentu, z Ubuntu 12.04. – Hibou57

13

polecenie odczytu osadzone Bash ma za -t parametr ustawić limit czasu:

-t timeout 
    Cause read to time out and return failure if a complete line of input is not 
    read within timeout seconds. This option has no effect if read is not reading 
    input from the terminal or a pipe. 

To powinno pomóc rozwiązać ten problem.

Edit:

Istnieją pewne ograniczenia na to rozwiązanie do pracy jako strona mężczyzna wskazuje: Opcja ta nie ma żadnego wpływu, jeżeli odczyt nie czyta dane wejściowe z terminala lub potoku.

Więc jeśli tworzę rury w/tmp:

mknod /tmp/pipe p 

Czytanie bezpośrednio z rury nie działa:

$ read -t 1 </tmp/pipe ; echo $? 

wisi na zawsze.

Działa, ale kot nie wychodzi.

Rozwiązaniem jest przypisanie rurę do deskryptora pliku:

$ exec 7<>/tmp/pipe 

a następnie odczytać z tego pliku deskryptora albo za pomocą przekierowania:

$ read -t 1 <&7 ; echo $? 
1 

Or opcję read-u:

$ read -t 1 -u 7 ; echo $? 
1 
+0

* ta opcja nie ma zastosowania, jeśli odczyt nie odczytuje danych wejściowych z terminala lub potoku. * Ma pewne znaczenie. Edytuję odpowiedź, aby dołączyć do przykładów roboczych. – gabuzo

+0

Nadal nie działa dla mnie, ale może używam spersonalizowanego basha. – michelemarcon

+0

Czy 'read -h' wyświetla komunikat pomocy z opcją' -t'? – gabuzo

Powiązane problemy