Mniej przeszkadza w mniej

13

Często przesyłam dane wyjściowe programu do mniej, np

produce_output | less

Działa to świetnie, dopóki nie produce_outputwytworzy dużej ilości danych wyjściowych. Jeśli szukam tekstu głęboko w pliku, mniej raportów

Calculating line numbers... (interrupt to abort)

Jeśli przerywam za pomocą Control + C, to również zabija produce_output, co powstrzymuje go przed dalszym wytwarzaniem. Czy jest jakiś sposób na przesłanie przerwania na mniej, aby produce_outputdziałało?

Wiem, że mógłbym skorzystać kill -INT less_process, ale myślę, że musi być lepsze rozwiązanie.

Ed McMan
źródło

Odpowiedzi:

15

Zwykle wszystkie procesy w potoku działają w tej samej grupie procesów , co powoduje, że wszystkie odbierają sygnał. Możesz użyć setsid foo | lessdo uruchomienia foow innym pgrp.

użytkownik1686
źródło
W świetle problemu podniesionego przez OP wydaje się, że decyzja o użyciu CTRL + C jako sposobu na przerwanie mniej jest bardzo niefortunna. Czy wiesz, dlaczego wybrano ten konkretny sygnał? Czy jakiś inny sygnał byłby mniej problematyczny?
Piotr Dobrogost
@PiotrDobrogost: Jaki inny sygnał zasugerowałbyś? Niewiele jest takich, którzy mają dedykowane skróty klawiaturowe, tylko SIGINT (Ctrl-C) i SIGQUIT (Ctrl- \), a ten drugi ma na celu natychmiastowe wyjście z programu, a nie tylko przerwanie. Reszta jest dostępna tylko za pośrednictwem kill.
user1686,
Wydaje się, że problem jest spowodowany przez użycie sygnału w celu mniejszego przerywania. Zamiast tego, gdyby był to jakiś normalny klawisz / skrót, nie mielibyśmy problemu w pierwszej kolejności. Jednak wydaje mi się, że potrzeba sygnału wynika z faktu, że proces nie może użyć selectdo oczekiwania na wejście jednocześnie z pliku / potoku i terminala.
Piotr Dobrogost
@PiotrDobrogost: Może tak Fdziała tryb (obserwuj). Rury i tty są pollable w ten sam sposób.
user1686,
Jak myślisz, dlaczego tak działa tryb śledzenia? Myślę, że przepływ zdarzeń polega na tym, że powłoka pobiera CTRL + C i wysyła sygnał SIGINT na mniej, który odbiera ten sygnał asynchronicznie bez słuchania klawiatury / terminala.
Piotr Dobrogost
9

Możesz wyłączyć numery linii za pomocą

   -n or --line-numbers

opcja.

produce_output | less -n
Matteo
źródło
-1: może rozwiązać problem inicjowania OP, ale nie robi nic, aby odpowiedzieć na aktualne pytanie OP (tj. Przerywać proces).
goldPseudo
2
Niestety, ale rozpoczęcie od mniejszej liczby funkcji, która nie jest pożądana, a następnie próba wysłania sygnału w celu wyłączenia funkcji, którą można wyłączyć za pomocą przełącznika, jest rozwiązaniem, a nie rozwiązaniem. Oczywiście rozwiązanie @grawity jest fajne (i głosowałem za nim), ale daj spokój: rozpoczęcie pierwszego procesu w innej grupie, aby móc wysłać sygnał do przerwania zadania (liczenia linii), które nie jest potrzebne, jest naprawdę trochę za małe dużo pracy.
Matteo
1
To uczciwe rozwiązanie problemu, który postawiłem w swoim pytaniu. Przerwania zatrzymują jednak więcej niż liczenie linii w mniejszym stopniu - na przykład przerywają także długie wyszukiwanie. Tak więc preferowane jest rozwiązanie @ grawity, ponieważ w mniejszym stopniu obejmowałoby ono użycie przerwań. Zły, że nie zająłem się tym jaśniej w pytaniu!
Ed McMan
@EdMcMan Pewnie też głosowałem za rozwiązaniem grawitacji i cieszę się, że mogę nauczyć się czegoś nowego, co zawsze może być przydatne.
Matteo
0

Przy pracy z dużą ilością danych wyjściowych bardzo pomocne okazało się wysłanie danych wyjściowych do pliku i użycie tail -flub less +Fobejrzenie, np .:

produce_output > out 2>&1 & less +F out

2>&1Składnia zapewnia, że zarówno stdout i stderr przejdź do out--- Usuń, że jeśli tylko chcesz stdout przechodząc do pliku. W ten sposób możesz sprawdzić dane wyjściowe na różne sposoby (nawet z innej maszyny), bez konieczności bałagania się w programie produkującym dane wyjściowe.

Zauważ, że 2>&1może być specyficzne dla bash (nie jestem pewien). Upewnij się, że masz wystarczającą ilość miejsca na dysku dla pliku wyjściowego :-)

jrennie
źródło
Tail po prostu pokaże ci plik, Ed stwierdził, że używa mniej interaktywnie (np. Musi przeszukać plik)
Matteo
2>&1to POSIX, goły >&to bashism.
user1686,
FWIW, 2> i 1 działa również w systemie Windows XP, 7, 2008 itd.
jftuga
@ Matteo: tak, powinienem był użyć less +Fw moim przykładzie; Właśnie zaktualizowałem swoją odpowiedź.
jrennie
1
@ Matteo: Zliczanie linii nie jest tym samym problemem less +F(ponieważ less +Fprzetwarza dane podczas ich generowania). Podany przeze mnie przykład nie ma tego samego problemu, co pierwotnie opublikowany: ctrl + c nie przerywa process_output. Jeśli ktoś nie dba o funkcjonalności „podążać”, można uruchomić produce_output > out 2>&1, a następnie less out. Problem produce_output | lesspolega na tym, że jeśli coś złamie rurę (np. Przypadkowe uderzenie w „q” less), to produce_outputumrze (bez specjalnej obsługi SIGPIPE).
jrennie
0

Możesz także po prostu to zrobić:

less +F -f <(produce_output)
Eric Woodruff
źródło