Η μεγάλη χελώνα Α`τουήν: Διαχείρηση και συντονισμός του ιστορικού εντολών του τερματικού

Στον σημερινό οδηγό θα δούμε το :turtle: atuin ένα πρόγραμμα που διαχειρίζεται το ιστορικό της γραμμής εντολών, και επιτρέπει την αναζήτηση και εκτέλεση παλιών εντολών , αλλά και το συντονισμό του ιστορικού μεταξύ πολλών υπολογιστών.


magical shell history

Of course, no other world was carried through the starry infinity on the backs of four giant elephants, who were themselves perched on the shell of a giant turtle. His name - or her name, according to another school of thought - was Great A’Tuin
– Terry Patchet “The Light Fantastic”

Εγκατάσταση

Σε όλες σχεδόν τις διανομές:

# do not run this as root, root will be asked for if required
bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh)

ή μιας και είναι γραμμένο σε Rust το εγκαθιστούμε μέσω Cargo.

Στο σύστημα μου η εντολή κατέβασε και εγκατέστησε ένα αρχείο deb και έκανε τις απαραίτητες αλλαγές στις ρυθμίσεις. Αλλά αν το εγκαθηστούμε με το χέρι θα ακολουθήσουμε τις οδηγίες εδώ.

Για το :bash: Bash βάζουμε στο αρχείο ~/.bashrc στο τέλος τα παρακάτω:

[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh
eval "$(atuin init bash)"

και θα πρέπει επίσης να κάνουμε:

curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh

Προαιρετικά για αυτόματη συμπλήρωση των ορισμάτων της εντολής

atuin gen-completions --shell bash --out-dir .
sudo mv atuin.bash /etc/bash_completion.d/atuin

Τέλος, προαιρετικά, εισαγωγή του παλιού ιστορικού με:

atuin import bash

Χρήση

Στο τερματικό με το που θα πατήσεις το πάνω βελάκι ή τον (γνωστό;) συνδιασμό CtrlR θα εμφανιστεί το περιβάλλον του atuin.

Με τον συνδυασμό CtrlR αλλάζουμε τον τρόπο λειτουργίας. Στην εικόνα είναι σε “directory” mode και δείχνει μόνο ότι εντολές έχω τρέξει στον συγκεκριμένο κατάλογο. Άλλα mode είναι το “host” που δείχνει εντολές που έτρεξαν στον συγκεκριμένο υπολογιστή ή το “session” για την τρέχουσα συνεδρία.

Προσωπικά βρήσκω πιο βολικό αυτό το mode και πρόσθεσα μια γραμμή filter_mode = "directory" στο αρχείο ~/.config/atuin/config.toml

Στη συνέχεια φιλτράρουμε προαιρετικά για την εντολή και με τα βελάκια επιλέγουμε αυτήν που θέλουμε. Υπάρχει υποστήριξη για απλά Regular expressions . Πατώντας Enter θα εμφανιστεί στο τερματικό για αλλαγές ή με Esc ακυρώνουμε.

Στα αρνητικά θα πρέπει να λεχθεί πως αντικαθιστά πλήρως τον μηχανισμό history του bash. To !cmd δεν λειτουργεί πλέον!
Επίσης δεν υπάρχει μηχανισμός διαγραφής μιας γραμμής του ιστορικού.

Αλλαγή των keybindings

Μπορεί να ξενίσει, τουλάχιστον στην αρχή η χρήση του πλήκτρου για ενεργοποίηση. Στην περίπτωση αυτή αλλάξτε το ~/.bashrc σε:

export ATUIN_NOBIND="true"
[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh
eval "$(atuin init bash)"
bind -x '"\C-r": __atuin_history'

Αρχικά το είχα έτσι, αλλά μετά κατάλαβα των το bash δεν ενημερώνει το δικό του αρχείο, οπότε το άφησα. Αλλά το δείχνω, για να δείξω πως μπορεί να αλλάξει κάποιος τα keybindigs αν θέλει. Αλλά δείτε το πρώτο σχόλιο για ένα καλύτερο παράδειγμα.

Προχωρημένη αναζήτηση

Ποια ήταν αυτή ή εντολή που είχα τρέξει πριν 2 μήνες και έκανα κάτι; Ξέρω δε μου έχει συμβεί ποτέ να κάνω grep στο ιστορικό, αλλά έχει συμβεί σε κάποιον φίλο. Αλλά αυτός ο φίλος δεν ήξερε ότι μπορούσε να κάνει:

# Search for all commands, beginning with cargo, that exited successfully
atuin search --exit 0 cargo

# Search for all commands, that failed, from the current dir, and were ran before April 1st 2021
atuin search --exclude-exit 0 --before 01/04/2021 --cwd .

# Search for all commands, beginning with cargo, that exited successfully, and were ran after yesterday at 3pm
atuin search --exit 0 --after "yesterday 3pm" cargo

Συντονισμός ιστορικού με πολλούς υπολογιστές

Μια άλλη δυνατότητα είναι να κρατάς συντονισμένο το ιστορικό μεταξύ πολλών υπολογιστών. Για τον σκοπό αυτό θέλεις ένα atuin server. Το ιστορικό αποθηκεύετε κρυπτογραφημένα και ο δημιουργός του atuin παρέχει έναν δωρεάν. Αλλά μπορείς να τρέξεις και ένα δικό σου server σε κάποιο Raspberry τοπικά.

Δεν το έχω υλοποιήσει και δεν το έχω πολύ ανάγκη, αν ποτέ το κάνω θα ενημερώσω τον οδηγό.

Το ιστορικό όπως έπρεπε να είναι

Ένας από τους λόγους που προτιμώ το zsh είναι που κρατούσε το ίδιο ιστορικό για όλα τα τερματικά. Το Bash δεν το έκανε αυτό με αποτέλεσμα να χάνω εντολές (κάτι χρήσιμο πχ για να τις μεταφέρω εδώ μέσα). Αλλά ταυτόχρονα ήταν και λίγο προβληματικό αυτό. Υπήρχε μια εποχή, μια εποχή με αργά vt100 που πραγματικά γνώριζα πως να δουλεύω το ιστορικό. Αλλά σήμερα :

Το :turtle: atuin επιστρέφει αυτή τη χαμένη παραγωγικότητα με ευκολία. Δοκιμάστε το.

ΥΓ: Ναι ο Terry Pratchet είναι από τους αγαπημένος μου συγγραφείς.
Και μιας και πλησιάζουν Χριστούγεννα μια πρόταση για ταινία:

4 «Μου αρέσει»

Βελτίωσα λίγο το setup:

export ATUIN_NOBIND="true"
__atuin_last() {
    tput rmkx
    HISTORY="$(RUST_LOG=error atuin history last --cmd-only 3>&1 1>&2 2>&3)"
    tput smkx

    READLINE_LINE=${HISTORY}
    READLINE_POINT=${#READLINE_LINE}
}

[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh
eval "$(atuin init bash)"
bind -x '"\C-r": __atuin_history'
bind -x '"\e[1;2A": __atuin_history'
bind -x '"\e[A": __atuin_last'

eval "$(starship init bash)"

Πλέον το δείχνει απλά την προηγούμενη εντολή, ενώ αν το πατήσεις μαζί με το Shift θα σου δείξει το atouin να επιλέξεις.

1 «Μου αρέσει»
1 «Μου αρέσει»

Update: Στην τελευταία έκδοση είναι απλούστερο

[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh
export ATUIN_NOBIND="true"
bind -x '"\C-r": __atuin_history'
bind -x '"\e[1;2A": __atuin_history'
eval "$(atuin init bash)"

Το export ATUIN_NO_BIND του λέει να μην κάνει τα readline bindings τα οποία τα κάνω στην συνέχεια χεράτα. Αν δεν θέλεις την παλία συμπεριφορά για το πάνω βελάκι, τότε θέλει απλά μόνο την τελευταία γραμμή.