Czy w bash mogę zorganizować wykonanie funkcji tuż przed uruchomieniem polecenia?
Jest $PROMPT_COMMAND
wykonywany przed wyświetleniem monitu, tj. Zaraz po uruchomieniu polecenia.
Bash's $PROMPT_COMMAND
jest analogiczny do precmd
funkcji zsh ; więc szukam bashowego odpowiednika zsh preexec
.
Przykładowe aplikacje: ustaw tytuł terminala na wykonywane polecenie; automatycznie dodaj time
przed każdym poleceniem.
command-line
bash
hook
Gilles
źródło
źródło
PS0
zmienną, która działa jak,PS1
ale jest używana po odczytaniu polecenia, ale przed jego wykonaniem. Zobacz gnu.org/software/bash/manual/bashref.html#Bash-VariablesOdpowiedzi:
Nie natywnie, ale można go zhakować za pomocą
DEBUG
pułapki. Ten kod konfiguruje siępreexec
iprecmd
działa podobnie do zsh. Wiersz poleceń jest przekazywany jako pojedynczy argument dopreexec
.Oto uproszczona wersja kodu do skonfigurowania
precmd
funkcji, która jest wykonywana przed uruchomieniem każdego polecenia.Ta sztuczka wynika z Glypha Lefkowitza ; dzięki bcat za zlokalizowanie oryginalnego autora.
Edytować. Zaktualizowaną wersję hacka Glypha można znaleźć tutaj: https://github.com/rcaloras/bash-preexec
źródło
"$BASH_COMMAND" = "$PROMPT_COMMAND"
Porównanie nie działa dla mnie i.imgur.com/blneCdQ.pngtime for i in {1..10}; do true; done
zajmuje normalnie 0,040 sekundy i 1,400 do 1,600 sekundy po aktywacji pułapki DEBUG. Powoduje to, że polecenie pułapki jest wykonywane dwa razy na pętlę - a w Cygwin rozwidlanie wymagane do wykonania sed jest zbyt wolne na około 0,030 sekundy dla samego rozwidlenia (różnica prędkości międzyecho
wbudowanym a/bin/echo
). Może coś, o czym warto pamiętać.PROMPT_COMMAND
zmiennej (np ograniczona;
), może trzeba użyć dopasowywania wzorców w drugim wierszupreexec_invoke_exec
funkcji, podobnie jak to:[[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]]
. Jest tak, ponieważBASH_COMMAND
reprezentuje każde z poleceń osobno.Możesz użyć
trap
polecenia (zhelp trap
):Na przykład, aby dynamicznie zmienić tytuł terminala, możesz użyć:
Z tego źródła
źródło
help trap
mówi: „Jeśli DEBUGA SIGNAL_SPEC, ARG jest wykonywany po każdym prostym poleceniu” [moje podkreślenie].trap '[ -n "$COMP_LINE" ] && [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ] && date "+%X";echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
. To umieszcza polecenie w tytule, a także drukuje aktualny czas przed każdym poleceniem, ale nie robi tego podczas wykonywania$PROMPT_COMMAND
.[ -z "$COMP_LINE" ]
.To nie jest funkcja powłoki, która jest wykonywana, ale napisałem wiersz
$PS0
zachęty, który jest wyświetlany przed uruchomieniem każdego polecenia. Szczegóły tutaj: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/$PS0
jest uwzględniony wbash
4.4, choć większość Linuksów zajmie trochę czasu 4.4 - możesz sam zbudować 4.4, jeśli chcesz; w takim przypadku prawdopodobnie powinieneś to podłożyć/usr/local
, dodać do/etc/shells
ichsh
do niego. Następnie wyloguj się i zaloguj ponownie, być może najpierwssh
do siebie @ localhost lubsu
do siebie jako test.źródło
Niedawno musiałem rozwiązać ten dokładny problem dla mojego pobocznego projektu. Stworzyłem dość solidne i odporne rozwiązanie, które emuluje pashxec i precmd zsh dla funkcjonalności bash.
https://github.com/rcaloras/bash-preexec
Pierwotnie był oparty na rozwiązaniu Glypha Lefkowitza, ale ulepszyłem go i zaktualizowałem. Chętnie pomogę lub w razie potrzeby doda funkcję.
źródło
Dziękuję za podpowiedzi! Skończyło się na tym:
Cieszyć się!
źródło
Napisałem metodę rejestrowania wszystkich poleceń / wbudowanych „bash” w pliku tekstowym lub na serwerze „syslog” bez użycia łaty lub specjalnego narzędzia wykonywalnego.
Jest bardzo łatwy do wdrożenia, ponieważ jest to prosty skrypt powłoki, który należy wywołać raz podczas inicjalizacji „bash”.
Zobacz metodę tutaj .
źródło