Korzystam z serwera Ubuntu 16.04 i chcę użyć narzędzia at
w mojej bieżącej sesji, aby zrobić coś za 1 minutę (powiedzmy, an echo
), bez podawania konkretnej daty i godziny - zaledwie 1 minutę do przodu od aktualnego czasu.
To się nie udało:
echo 'hi' | at 1m
Powodem wybiorę at
nad sleep
dlatego handicapy snu bieżącej sesji i jest dla nich bardziej nadaje się do poleceń opóźnienia w innej sesji, zamiast pracy z jednych my przez większość czasu. AFAIR, at
nie zachowuje się w ten sposób i nie utrudnia mojej sesji.
Aktualizacja_1
Według odpowiedzi Pied Piper próbowałem:
(sleep 1m; echo 'hi') &
Mam problem z tą metodą: strumień „cześć” jest drukowany wewnątrz mojego głównego monitu, a także dodaje pusty dodatkowy monit ( _
) bezpośrednio pod głównym monitem, który go zawiera, patrz:
USER@:~# (sleep 1m; echo 'hi') &
[1] 22731
USER@:~# hi
^C
[1]+ Done
Aktualizacja_2
Na odpowiedź Petera Corde'a próbowałem:
(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
Działa to poprawnie w Bash 4.4, ale najwyraźniej nie w niektórych starszych wersjach (patrz komentarze w odpowiedzi). Osobiście korzystam z Bash 4.3 we własnym środowisku.
Odpowiedzi:
Nie, nie jest to „wydrukowane na twoim
stdin
”.Jeśli naciśniesz klawisz Return, nie będzie próbował uruchomić się
hi
jako polecenie. Tyle tylko, że tłoecho
drukowane było,hi
gdy kursor znajdował się za twoim monitem.Być może chcesz wydrukować wiodący nowy wiersz , na przykład
(sleep 1m && echo -e '\nhi' &)
. (Dostosuj odpowiednio doecho
powłoki. Lub użyjprintf
dla przenośności.)Umieszczam
&
wnętrze podpowłoki, aby „wyłączyć” zadanie w tle, abyś także unikał „szumu”[1]+ Done
. Z&&
pomiędzy poleceniami,&
odnosi się do całego łańcucha związek-polecenia, więc wraca do powłoki wiersza od razu, zamiast czekać nasleep
do wyjścia jak dałaby(sleep 1; echo ... &)
Oto, co się stanie (z 1-sekundowym opóźnieniem):
Bash nie wie, że
echo
coś wydrukował, więc nie wie, że musi ponownie wydrukować monit lub wyczyścić ekran. Możesz to zrobić ręcznie za pomocącontrol-L
.Możesz napisać funkcję powłoki, która pobiera bash, aby ponownie wydrukować monit po
echo
zakończeniu . Samo działanieecho "$PS1"
nie odtworzy już wpisanych znaków.kill -WINCH $$
w moim systemie pojawia się bash, aby ponownie wydrukować wiersz zachęty bez czyszczenia ekranu, pozostawiająchi
wiersz sam przed monitem. SIGWINCH jest wysyłany automatycznie, gdy zmienia się rozmiar okna WINDow, a reakcja bash na to dzieje się tak, jak chcemy.Może działać z innymi powłokami, ale nie próbuję uczynić tego w 100% przenośnym / POSIX. ( Niestety działa to tylko na bash4.4, nie na bash4.3 lub zależy od niektórych ustawień, których nie znam )
Można to łatwo zawinąć w funkcję powłoki, która pobiera argument uśpienia i komunikat.
bash 4.3 nie drukuje ponownie swojego monitu po SIGWINCH, więc to nie działa. Mam
shopt -s checkwinsize
włączone na obu systemach, ale działa tylko w systemie Bash 4.4 (Arch Linux).Jeśli to nie działa, możesz spróbować
(sleep 2 && echo -e '\nhi' && echo "$PS1" &)
, który „działa”, jeśli wiersz poleceń jest pusty. (Ignoruje również ustawioną możliwośćPROMPT_COMMAND
).Nie ma naprawdę czystego sposobu na zmiksowanie wyjścia terminala z tym, co możesz zrobić na swoim terminalu później, gdy zadziała timer. Jeśli jesteś w trakcie przewijania czegoś
less
, możesz łatwo tego przegapić.Jeśli szukasz czegoś z interaktywnymi wynikami, sugeruję odtworzenie pliku audio. np. z odtwarzaczem wiersza poleceń, takim jak
mpv
(fajny fork MPlayera2). Lub wybierz plik wideo, aby otworzyć nowe okno.Możesz chcieć
echo
otworzyć swój nowy xterm / konsole / gnome-terminal. Użyj opcji, która utrzymuje terminal otwarty po wyjściu polecenia.źródło
Enter
zdarzenie naciśnięcia klawisza, zaraz po pojawieniu się echa, aby automatycznie wrócić do głównego monitu konsoli ?(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
.kill -WINCH $$
nie odświeżać zachęty powłoki uruchomiony w terminalu. Właśnie o to chodziło. Naciśnięcie Enter spowoduje przesłanie częściowo wpisanego polecenia, ale WINCH nie, jak pokazałem. Jeśli nic nie wpisałeś, pojawia się pusty monit.rm -rf ~/some/directory
, Enter w niewłaściwym czasie może się uruchomićrm -rf ~/
. (Wskazówka bezpieczeństwa: zakończ pisanie ścieżek, a następnie naciśnij klawisz Control-a i zmieńls
narm -rf
, aby tłuste palce Enter w każdej chwili nie zrujnowały twojego dnia.)(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
i po pojawieniu się echa dostałem pusty monit, dopiero po trafieniuEnter
wróciłem do głównego ... Przepraszam, jeśli cię źle zrozumiem, jestem całkiem nowy w Bash.screen
sesji (i tylko przez SSH) na starszym systemie Ubuntu, i dostałem zachowanie, które opisujesz.Prawidłowe w użyciu jest
at <timespec>
, gdzie<timespec>
jest specyfikacja czasu. Możesz również użyć tej-f
opcji, aby określić plik zawierający polecenia do wykonania. Jeśli-f
i nie jest używane przekierowanie, at przeczyta polecenia do wykonania ze standardowego wejścia (standardowe wejście).W twoim przykładzie, aby wykonać „jakieś polecenie” (wybrałem „jakieś polecenie”, aby być „echo cześć” w poniższym przykładzie) minutę po naciśnięciu klawisza enter (teraz),
<timespec>
należy użyćnow + 1 minute
. Tak więc, aby uzyskać pożądany wynik za pomocą rozwiązania jednowarstwowego, użyj poniższego polecenia:echo 'echo hi' | at now + 1 minute
Ma to (i zrobi) uruchomienie
echo hi
polecenia po minucie. Problem polega na tym, żeecho hi
polecenie zostanie wykonane przez polecenie at w atrapie tty, a dane wyjściowe zostaną wysłane do skrzynki pocztowej użytkownika (jeśli jest poprawnie skonfigurowana - co wymaga bardziej szczegółowego wyjaśnienia, jak skonfigurować skrzynkę pocztową w maszyna uniksowa i nie jest objęta zakresem tego pytania). Najważniejsze jest to, że nie będziesz mógł bezpośrednio zobaczyć wynikuecho hi
w tym samym terminalu, z którego wydałeś polecenie. Najłatwiejszą alternatywą jest przekierowanie go do „jakiegoś pliku”, na przykład:echo 'echo hi > /tmp/at.out' | at now + 1 minute
W powyższym przykładzie „jakiś plik” jest,
/tmp/at.out
a oczekiwanym rezultatem jest to, że plikat.out
w / tmp jest tworzony po minucie i zawiera tekst „cześć”.Oprócz
now + 1 minute
powyższego przykładu, można zastosować wiele innych specyfikacji czasu, nawet niektóre złożone. Polecenie at jest wystarczająco inteligentne, aby interpretować te całkiem czytelne dla ludzi, takie jak poniższe przykłady:now + 1 day
,13:25
,mid‐night
,noon
, ...Więcej informacji na temat możliwych specyfikacji czasu można znaleźć na stronie podręcznika użytkownika at, ponieważ możliwe odmiany są dość obszerne i mogą obejmować daty, czasy względne lub bezwzględne itp.
źródło
at
domyślnie wysyła dane wyjściowe pocztą, ale musi to być odpowiednio skonfigurowane do działania.at <timespec>
i flagi, której użyłeś i czy pasuje do Xenial Ubuntu 16.04.Uruchom
sleep
w podpowłoce:Uwaga: w systemie Linux argument można spać w ciągu kilku sekund lub z przyrostkiem s / m / h / d (dla sekund, minut, godzin, dni). Na BSD argument musi być podany w sekundach
źródło
stdin
), a nie w moimstdout
(jak w przypadku zwykłegoecho
).(sleep 10s; echo 'hi') & 1>
. Teraz czytam więcej na ten temat.stdin
istdout
. Nie mają one nic wspólnego z tym, gdzie rzeczy pojawiają się na twoim terminalu; zamiast tego powinieneś interpretować je w odniesieniu do konkretnego procesu (w zasadzie programu). Standardowe dane wejściowe („standardowe wejście”) dla procesu to źródło, z którego proces może odczytywać dane, a standardowe dane wyjściowe procesu („standardowe wyjście”) to miejsce docelowe, do którego może zapisywać dane. Tymi źródłami i miejscami docelowymi mogą być inne programy, pliki lub sam terminal (wpisywane przez ciebie pliki idą do standardowego wejścia i wyświetlane jest wszystko, co przychodzi do standardowego wyjścia).Że nie powiodło się, ponieważ jesteś potokiem wyjście
echo "hi"
, które jest tylkohi
doat
, aleat
spodziewa się, że jest to wejście może być wykonywane przez powłokę domyślnym systemowym (zwykle bash, ale czasami coś innego w zależności od systemu).To:
osiągnie to, co próbujesz zrobić. Wykorzystuje konstrukcję powłoki zwaną „dokumentem tutaj”, co jest ogólnie przyjętym sposobem wykonywania tego typu czynności (ponieważ obsługuje wiele wierszy lepiej niż przy użyciu
echo
polecenia i nie wymaga tworzenia nowego pliku, tak jak trzeba to zrobić zcat
) i przekłada się na nieco bardziej skomplikowany odpowiednik przy użyciuecho
:Prawdopodobnie warto zauważyć, że
at
wyśle wszelkie dane wyjściowe polecenia do użytkownika, który wywołałat
polecenie, zamiast łączyć dane wyjściowe z terminalem, tak jaksleep
zrobiłoby to polecenie opóźnione w podpowłoce. W szczególności oznacza to, że dopóki nie dostosujesz systemu lub nie zamierzasz czytać lokalnego bufora poczty, nie będziesz w stanie uzyskać wyjścia poleceńat
.źródło
syntax error. Last token seen: m Garbled time
. Nie mam pojęcia dlaczego. Używam Ubuntu 16.04, Bash 4.0. Może zrobiłeś to na innym systemie. Nawet gdy piszęat
bez żadnych dalszych argumentów --- wciąż pojawia się ten sam błąd. Więcej danych tutaj .at 1m
nie działa dla kompatybilnego z POSIX-emat
. Polecenie musiałoby byćat now + 1 minute
at
, po prostu zakładałem, że masz wersję, która zaakceptowała tę składnię.at 1m
nie jest POSIX- em, ale implementacje kompatybilne z POSIX- emat
mogą dowolnie interpretować to, co chcą, nie czyni toat
implementacji mniej zgodną, aby interpretować to tak samo, jaknow + 1 minute
zwracanie błędu lub znaczenia miesiąc temu . IOW, toat 1m
kod, który nie jest POSIX.Połącz odpowiedź @Peter Cordes i tę odpowiedź /programming/23125527/how-to-return-to-bash-prompt-after-printing-output-from-backgrounded-function/23125687#23125687
Poniższy kod pochodzi z drugiej odpowiedzi, z niewielką zmianą mojego. Skompiluj go do pliku a.out (dowolna nazwa)
Następnie uruchom poniższe polecenie. (Umieściłem a.out w katalogu dir / tmp /, być może trzeba będzie zmienić na swój)
lub
BTW,
kill -WINCH $$
działa dobrze dla mnie z Bash 4.3 na Gentoo.źródło
Opierając się na powyższych odpowiedziach, możesz osadzić polecenie skierowane do wyjścia na terminalu:
echo "echo hi >$(tty); kill -WINCH $$" | at now + 1 minute
tty
Polecenie zwraca ścieżkę urządzenie swojego obecnego terminalu, zamykając go w$(...)
ma bash wykonać go w sub-shell, a polecenie kill wysyła sygnał do bieżącego procesu, który będzie miał bash ponownego wydrukowania szybka jego $ PS1.źródło