TL;DR
Za pomocą prostego polecenia można spowodować, by po każdej zmianie katalogu w konsoli była wypisywana lista plików. Rozwiązanie to oszczędza sporo czasu i ułatwia zorientowanie się w bieżącej strukturze katalogów.
Idea
Linuksowe wygi pewnie nie mają tego zwyczaju – po prostu wiedzą, gdzie wylądowali po wydaniu polecenia „cd”. Ja jednak nie potrafiłem się pozbyć tego odruchu – zwłaszcza po wpisaniu długiej, skomplikowanej ścieżki korciło mnie, żeby sprawdzić, czy na pewno nic nie pomyliłem. Rzecz jasna w bashu klawisz Tab uzupełnia nazwy katalogów, ale jednak… może to nie tu?
Najwyraźniej nie ja jeden się z tym borykałem, bo któregoś razu mój syn, pochwalił się, że wymyślił „auto-ls” i że mu się bardzo przydaje. Pomysł okazał się strzałem w dziesiątkę – klawisze „L” oraz „S” odetchnęły z ulgą.
Idea jest taka, żeby po wpisaniu „cd” + nazwa katalogu wykonało się nie jedno, a dwa polecenia. Można do tego wykorzystać alias.
Czym jest alias
Alias to rodzaj “makra”, najczęściej używanego, by od razu podawać pożądane parametry do wydawanych poleceń. Ja na przykład korzystam z takiej definicji:
alias ls='ls --time-style="+%Y.%m.%d %H:%M:%S" --color=always'
Powoduje to, że za każdym razem, kiedy listuję katalog data jest sformatowana tak jak sobie tego życzę i zawsze włączone jest kolorowanie listingu (co czasem sprawia kłopoty, ale i na to jest sposób, o czym za moment).
Możemy więc zrobić sobie alias:
cd=
no, właśnie, co dalej?
Rozwiązanie
Do aliasu można przypisać np. skrypt, ale tym razem nie jest to możliwe. Dlaczego? Otóż każde polecenie basha (w tym skrypt) otwiera nową sesję, wykonuje swoją robotę i wraca do procesu, z którego zostało wywołane. Wszystkie operacje (również zmiany katalogu) dotyczą wyłącznie tej nowej sesji.
Trzeba sięgnąć po inne sposoby. Bash zna pojęcie funkcji. Funkcja jest wykonywana w ramach sesji, w której została wywołana, wykonuje swoją robotę, modyfikując tę sesję.
Potrzebna jest więc funkcja, która zrobi dwie rzeczy, jedną po drugiej:
cdls(){ cd $1; ls --color=always -lh; }
W ramach funkcji wykonywane są dwa polecenia, oddzielone od siebie średnikiem:
- zmiana katalogu (cd $1)
- lista katalogu kolorowana, w kolumnach i z wielkościami plików podanymi po ludzku.
Akurat dla mnie było tak najwygodniej, ale każdy może sobie sformatować tę listę jak mu się podoba – odsyłam do man ls.
Pozostaje jeszcze przypisać tę funkcję do… polecenia cd:
alias cd='cdls'
Można to wręcz ująć w jednej linii i opatrzyć komentarzem:
cdls(){ cd $1; ls --color=always -lh; }; alias cd='cdls' # automatyczny listing po cd
Gotowe. Każda zmiana katalogu spowoduje wypisanie listy plików nowego katalogu roboczego.
Dlaczego to działa? Otóż aliasy mają pierwszeństwo przed oryginalnymi poleceniami. Jeśli jest zdefiniowany alias to ani skrypt ani polecenie o tej nazwie nie zostanie wykonane – zostanie wykonany alias.
…i niech tak będzie
Aby tę konfigurację mieć na stałe i nie definiować funkcji przy każdym otwartym oknie (każdy nowy terminal to nowa sesja basha) trzeba te polecenia wpisać do pliku konfiguracyjnego ~/.bashrc lub ~/.profile. Różnica między tymi plikami jest taka, że pierwszy jest odczytywany przy każdej nowej sesji bash, drugi zaś – raz, w momencie logowania. Naszą linię z aliasem sugerowałbym wpisać do ~/.profile – ja jej nie zmieniałem od kilku lat, a ~/.bashrc zwykle zapełnia się mnóstwem parametrów i z czasem coraz trudniej się w nim połapać.
Sposób na obejście – na wszelki wypadek
No, dobrze, a jeśli nie chcemy tego listingu (bo np. mamy małe okienko, może tryb awaryjny)?
Jak wspomniałem aliasy mają pierwszeństwo przed oryginałami. Jeśli mamy do czynienia z poleceniem zewnętrznym (to znaczy takim, które jest plikiem wykonywalnym) można podać ścieżkę do niego. Za pomocą polecenia type możemy wyświetlić informacje o poleceniu (w podanym przykładzie definicję aliasu, który został do polecenia przypisany)
$ type ls ls jest /usr/bin/ls
wpisanie /usr/bin/ls wywoła oryginalne polecenie, a nie alias.
Z cd sprawa nie jest taka prosta, bo to nie jest polecenie zewnętrzne i „which cd” po prostu nie zwraca nic. Jest to funkcja wbudowana w plik wykonywalny bash.
Jednak w Linuksie rzadko się zdarza, żeby sytuacja była bez wyjścia: i tym razem bash oferuje rozwiązanie problemu. Mianowicie wystarczy co najmniej jeden znak poprzedzić „backslashem”:
\cd
W ten sposób zostanie wykonane oryginalne polecenie, a nie jego alias.
Dzięki jednej linii, dopisanej do pliku konfiguracyjnego oszczędza się naprawdę mnóstwo czasu i stukania w klawisze. Mała rzecz, a cieszy 🙂