Jak uruchomić program w tle

9

Program Boblight nie działa w tle. Nie ma zauważalnej różnicy między wykonywaniem

sudo boblightd

i

sudo boblightd& 

Jak rozwiązać ten problem polegający na tym, że konsola nie blokuje dalszych danych wejściowych?

pi@raspberrypi ~/boblight/boblightd-for-raspberry-master $ sudo boblightd
Boblightd 2.0 (optimized version for raspberry) (c) 2013 Speedy1985 and Heven)
(InitLog)                       start of log /root/.boblight/boblightd.log
(PrintFlags)                    starting boblightd
(CConfig::LoadConfigFromFile)   opening /etc/boblight.conf
(CConfig::CheckConfig)          checking config lines
(CConfig::CheckConfig)          config lines valid
(CConfig::BuildConfig)          building config
(CConfig::BuildConfig)          built config successfully
(main)                          starting devices
(CClientsHandler::Process)      opening listening TcpSocket on *:19333
(CDevice::Process)              ambilight: starting with output "/dev/spidev0.0"
(CDevice::Process)              ambilight: setting up
(CDevice::Process)              ambilight: setup succeeded


pi@raspberrypi ~/boblight/boblightd-for-raspberry-master $ sudo boblightd&
[1] 2289
pi@raspberrypi ~/boblight/boblightd-for-raspberry-master $
Boblightd 2.0 (optimized version for raspberry) (c) 2013 Speedy1985 and Heven)
(InitLog)                       start of log /root/.boblight/boblightd.log
(PrintFlags)                    starting boblightd
(CConfig::LoadConfigFromFile)   opening /etc/boblight.conf
(CConfig::CheckConfig)          checking config lines
(CConfig::CheckConfig)          config lines valid
(CConfig::BuildConfig)          building config
(CConfig::BuildConfig)          built config successfully
(main)                          starting devices
(CClientsHandler::Process)      opening listening TcpSocket on *:19333
(CDevice::Process)              ambilight: starting with output "/dev/spidev0.0"
(CDevice::Process)              ambilight: setting up
(CDevice::Process)              ambilight: setup succeeded
użytkownik2534685
źródło
8
Powiedz:sudo boblightd > /dev/null 2>&1 &
devnull
Jeśli nie robisz tego w celu uczenia się, użyj dmenu. To jest proste i całkiem nieźle sobie radzi.
Nishant,

Odpowiedzi:

22

Polecenie „ [1] 2289po” w tle pokazuje, że działało i rzeczywiście zostało umieszczone w tle.

Ale dane wyjściowe polecenia będą nadal przekazywane do terminala, chyba że nastąpi przekierowanie. Oto kompleksowy sposób, aby to zrobić:

sudo boblightd >std.txt 2>err.txt &

Jeśli chcesz, aby zarówno stdout, jak i stderr przechodziły do ​​tego samego pliku:

sudo boblightd >std.txt 2>&1 &

I oczywiście, jeśli nie zależy ci na wyjściu jednego lub obu strumieni, możesz wysłać na /dev/nulladres zamiast nazwy pliku.

sudo boblightd >/dev/null 2>err.txt &

(ten przykład odrzuca standardowe wyjście, ale zachowuje stderr, na wypadek, gdyby coś poszło nie tak).


AKTUALIZACJA

Powyższe opiera się na braku wiedzy o tym, co to jest blight. Widzę w innej odpowiedzi, że ma tryb demona, więc w tym przypadku należy go użyć.

BTW, powyższe zakłada, sudoże nie poprosi o hasło i że nie zamkniesz okna terminala. W przypadku tych pierwszych zwykle osobiście używam sudo bashwtedy do pisania boblightd >std.txt 2>err.txt &. Innym sposobem jest wykonanie polecenia sudo lslub wykonanie nieszkodliwego polecenia, aby upewnić się, że dostęp zostanie zbuforowany.

W tym drugim przypadku nohupjest to magiczne polecenie, aby upewnić się, że będzie działać nawet po opuszczeniu budynku. To pójdzie po sudoi przed właściwym rozkazem. Np sudo nohup boblightd >std.txt 2>err.txt &. Albo sudo bashwtedy nohup boblightd >std.txt 2>err.txt &, następnie exit(do opuszczenia konta root).

Darren Cook
źródło
Należy również pamiętać, że sudopróba zapytania o hasło zakończy się niepowodzeniem, ponieważ procesy w tle nie mogą odczytać STDIN.
Patrick
Dzięki @Patrick. Właśnie odpowiedziałem na bezpośredni problem w pytaniu, ale ponieważ zyskuje to trochę uwagi, zaktualizowałem o wzmiankę o pytaniu o hasło i „nohup”.
Darren Cook
5

Myślę, że możesz użyć polecenia nohup w następujący sposób:

nohup sudo boblightd &

spowoduje to umieszczenie danych wyjściowych polecenia w pliku nohup.out w bieżącym katalogu.

Możesz także użyć polecenia screen w następujący sposób: najpierw utwórz ekran:

screen -S your-sreen-name

następnie uruchom polecenie:

sudo boblightd

Aby zapisać ekran i powrócić do terminala, wpisz Ctrl+AD( Ctrl+Ajest wskazówką screen, że chcesz coś zrobić, a Dnastępnie „d” przerywa sesję bez jej zatrzymywania).

przywróć ekran:

screen -d -r your-screen-name

źródło
4

Będziesz musiał przekierować stdout i stderr na coś innego niż domyślne, aby je ukryć. Komentarz @ devnull pokazuje, jak to zrobić. To pierwszy krok.

Jeśli po prostu użyjesz &do odłączenia swojego programu, zostanie on automatycznie zabity po wylogowaniu. Prawdopodobnie nie tego chcesz. Musisz użyć nohuppolecenia, aby temu zapobiec:

nohup sudo boblightd > boblight.out 2> boblight.err < /dev/null &

Zauważ, że sudoprawdopodobnie poprosi o hasło: nie dostanie żadnego i nie zauważysz, że prosi o podanie hasła, ponieważ każde wyjście / wejście jest przekierowywane. W każdym razie masz różne rozwiązania, aby to osiągnąć:

  • Uruchom sudopolecenie wcześniej, sudozapisze twoje hasło. To szybki i szybki sposób.
  • Usuń &, podaj sudohasło, a następnie wyślij proces do tła za pomocą CTRL + Z.
  • Można również skonfigurować sudo, aby nie pytał o hasło dla tego konkretnego użytkownika i pary plików wykonywalnych. Pamiętaj, że może to być możliwe naruszenie bezpieczeństwa…
Marc Plano-Lesay
źródło
Czy lepiej mieć nohup przed czy po sudo? Jak sudozdobyć hasło, gdy je uruchomisz nohup?
Aaron Digulla
1
Cóż, to dobra uwaga: nie będzie. Masz tutaj wiele rozwiązań: wcześniej uruchom polecenie sudo, sudo zapisze twoje hasło. To szybki i szybki sposób. Innym byłoby usunięcie &, podanie sudohasła, a następnie wysłanie procesu do tła ctrl + z. Możesz także skonfigurować, sudoaby nie pytać o hasło dla tego konkretnego użytkownika i pary plików wykonywalnych.
(Dodałem to do odpowiedzi.)
Zwykle tak robię sudo bash, a następnie uruchamiam nohuppolecenie z nowej powłoki.
W rzeczywistości niepoprawne jest to, że jeśli używasz tylko &procesu w tle, zostanie on zabity podczas wylogowywania. Tylko wtedy, gdy bash zostanie zabity przy pomocy SIGHUP, ZWIĘKSZY twój program. Ale wylogowanie się nie powoduje ZWIĘKSZENIA. Jeśli wpiszesz logoutlub użyjesz CTRL + D, bash zakończy działanie i zakończy proces. SIGHUP jest wysyłany po zamknięciu emulatora terminala w GUI.
Patrick,
2

Boblightd

W przypadku boblightd dane wyjściowe wysyłane do stderr są już przechwytywane w jego pliku dziennika (domyślnie ~ / .boblight / boblightd.log ), więc nie trzeba go przechwytywać i można go odrzucić. Ponadto boblight nie rozwidla się domyślnie, ale można to zrobić, włączając w poleceniu opcję -f .

Sugeruję wypróbowanie następujących opcji:

sudo boblightd -f >/dev/null 2>/dev/null

(szczegóły z dokumentacji projektu )

Bardziej ogólnie

Procesy rozpoczęte od powłoki zakończą się po wyjściu z powłoki. Jak zauważyli inni, używanie Ctrl-Zpodczas uruchamiania procesu na pierwszym planie zwraca kontrolę nad powłoką. W tym momencie proces jest jednak zatrzymywany . bg Będą potrzebne polecenie, aby proces uruchomiony ponownie, ale pobyt w tle. Wymaga identyfikatora procesu lub numeru zadania (jak zwykle numery zadań są poprzedzone%), więc używając drugiego przykładu, możesz wydać

bg %1

lub

bg 2289

Proces będzie teraz działał w tle, ale nadal będzie dołączony do powłoki. Łącze do powłoki można rozerwać za pomocą disownpolecenia, co pozwala uniknąć pomyłek z nohup / sudo. Podobnie jak w przypadku bg, disownwymaga tylko identyfikatora procesu lub numeru zadania

na przykład

disown 2289

Możesz teraz bezpiecznie opuścić powłokę, tak jakbyś uruchomił proces za pomocą nohuppolecenia

Chilledrat
źródło
1

Ponieważ odpowiedź jest już ułożona w komentarzu. Czułem, że dobrze byłoby opublikować trochę wyjaśnień na ten temat jako rzeczywistą odpowiedź.

Tak więc droga jest następująca: sudo boblightd > /dev/null 2>&1 &

Są tu 3 ważne części. Najważniejsze jest &na końcu linii. Powoduje, że powłoka nie czeka na zakończenie polecenia przed oddaniem kontroli. Wyjmuje również standardowe wejście z klawiatury. To umieszcza pracę w tle.

Ale nadal pozostawiłoby to wyjście z powrotem w konsoli. Aby temu zapobiec, istnieje >symbol przekierowujący standardowe wyjście ( /dev/nullw tym przypadku).

W tym momencie nadal można uzyskać dane wyjściowe z wywołanego polecenia get to screen. To byłby błąd standardowy. Wreszcie jest 2>&1magia. To przekierowuje wyjście ze standardowego strumienia błędów na standardowe wyjście.

2i 1pochodzą ze standardowych deskryptorów plików. 0byłoby stdin, 1- stdout, 2- stderr.

Jeśli potrzebujesz, możesz przekierować dane wyjściowe do pliku.

Istnieją polecenia zaprojektowane do interakcji z zadaniami w tle. jobsa fg.

W screenrazie potrzeby możesz także grać z bardziej zaawansowanymi rozwiązaniami, takimi jak polecenie.

luk32
źródło