
Ten poradnik piszę w równym stopniu dla Was co dla siebie. Znajdziesz w nim opis kilku praktycznych poleceń przydatnych w codziennej pracy w Linuxie. Nie mam dobrej pamięci do składni i nazw poleceń więc na przestrzeni lat posługiwałem się rozmaitymi notatkami, plikami tekstowymi i dokumentami. Często odwiedzając Stack Overflow mam déjà vu, pewnie nie bez powodu. Wiele z najpopularniejszych odpowiedzi na pytania takie jak „jak skopiować plik przez SSH” czy „jak wyszukać tekst rekursywnie w całym folderze” odwiedzam regularnie co kilka miesięcy.
W tym artykule chciałbym stworzyć i podzielić się z Tobą swoim zestawem kilku przydatnych poleceń w Linuxie. Ja najczęściej korzystam z dystrybucji opartych o Debian (a więc Ubuntu oraz Mint). Jeżeli korzystasz z innych dystrybucji możliwe że niektóre z poleceń lub ścieżek plików systemowych będą u Ciebie wyglądały inaczej (na 100% te dotyczące zarządzania pakietami, a więc wszędzie tam gdzie ja używam apt-get
)
Absolutne podstawy
Na starcie chciałbym wrzucić kilka zdecydowanie podstawowych poleceń. Robię to ponieważ sporo osób trafia na tą stronę szukając właśnie najważniejszych, podstawowych komend w Linuxie.
pwd
– wyświetla bieżący folderls
– wyświetla listę plików w folderze. Posiada wiele przydatnych parametrów, np.-l
aby wyświetlić „tabelkę” ze szczegółowymi danymi czy -t aby posortować pliki po czasie modyfikacji. Jest jeszcze parametr -a który spowoduje wyświetlenie plików ukrytych. Tak jak w każdym poleceniu, parametry jednoliterowe można łączyć, a więc np.ls -alt
cd
– zmiana folderu.cd ..
– przejście do folderu nadrzędnego.cd ~
– przejście do folderu domowego dla danego użytkownikaifconfig -a
– wyświetla adresy IP interfejsów sieciowych Twojej maszyny. Jeśli chcesz sprawdzić adres publiczny możesz „zapytać” curl’em chociażby ifconfig.me (curl ifconfig.me)nano
– chyba najwygodniejszy edytor tekstowy dla Linuxa, instalowany standardowo w większości dystrybujcji. Otwieramy plik poprzeznano nazwa_pliku
cdn…
Jak dodać alias (skrót) polecenia
Aliasy ułatwiają życie – pozwalają zapisać złożone polecenia pod przystępnym, krótkim skrótem. Mechanizm persystencji aliasów zależy od dystrybucji Linuksa oraz używanego shella. Ja korzystam z Bash’a dlatego aliasy uzupełniam w pliku ~/.bashrc
. Ten plik wywoływany jest za każdym razem kiedy startujesz Bash’a, a więc np. otwierasz nowe okno terminala lub logujesz się na maszynę przez SSH.
Oto ostatnie dwie linie mojego pliku .bashrc
gdzie dodałem dwa polecenia przyśpieszające (delikatnie) pracę z wirtualnymi środowiskami w Pythonie (workon
aktywuje środowisko wirtualne, workoff
je dezaktywuje):
alias workon='source ./.env/bin/activate'
alias workoff='source ./.env/bin/deactivate'
Po dodaniu aliasów do .bashrc
nie będą działały od razu – Bash nie monitoruje zmian w tym pliku, przetwarza go natomiast przy każdorazowym uruchomieniu nowego shella. Musisz zatem:
- uruchomić ponownie shella (a więc nowe okno terminala/przelogowanie się poprzez SSH, etc.), lub
- użyć komendy
source ~/.bashrc
która „załaduje” ponownie.bashrc
, w tym nowo utworzone aliasy.
Oczywiście samo polecenie alias, np.: alias workon='source ./.env/bin/activate'
również zadziała, ale alias który tak stworzysz będzie dostępny tylko do końca bieżącej sesji. Właśnie dlatego potrzebujemy pliku .bashrc
– dzięki niemu alias jest zawsze dostępny.
Aliasy niestety nie mogą posiadać parametrów. Więc wykorzystujemy je tam gdzie składnia polecenia jest stała. Jeżeli chcesz użyć parametrów, poczytaj o funkcjach w shellu, np. tutaj: Make a Bash alias that takes a parameter?. Funkcję napisaną w Bashu również wrzucasz do pliku .bashrc
– będzie wtedy dostępna w każdym nowo otwartym shellu.
Jak wyszukać polecenia którego kiedyś użyłam/em?
Korzystamy z dwóch podstawowych poleceń oraz | czyli tzw. pipe (rura). Pozwala ona na połączenie strumienia wyjściowego jednego polecenia z wejściem kolejnego. My skorzystamy z cat
– aby wyświetlić zawartość całej historii shella oraz grep
– aby wyszukać w tej historii wierszy z zadaną frazy.
$ cat ~/.bash_history | grep build
docker-compose build
docker-compose build
docker-compose up --detach --build influxdb
docker-compose up --detach --build influxdb
Zwróć uwagę, że pracując z Bash’em, historia znajduje się w pliku ~/.bash_history
. Jeśli u Ciebie ta kombinacja nie działa – możliwe że korzystasz z innego shella.
Oczywiście lepiej skorzystać z history
, które działa poprawnie w większości dystrybucji i powłok systemowych (piekna fraza, po angielsku shell) a więc:
$ history | grep build
docker-compose build
docker-compose build
docker-compose up --detach --build influxdb
docker-compose up --detach --build influxdb
W przykładzie powyżej build
to wyszukiwana fraza. Grep
oczywiście przyjmuje wyrażenia regularne (Regular Expression, regexp czy regex) ale tak jak w przykładzie powyżej – prosta fraza również jest poprawnym parametrem.
Jak wyszukać frazę w całym folderze (rekursywnie)?
Albo inaczej, jak znaleźć wszystkie wystąpienia frazy:
$ grep -rnw . -e 'http:/'
To polecenie pokaże wszystkie wystąpienia frazy w plikach ze wskazanego folderu w trybie rekursywnym, a więc z uwzględnieniem zawartości podfolderów. W tym przykładzie szukam frazy http:/
w bieżącym folderze, którego ścieżka w Linuxie to kropka – .
. Więcej na temat parametrów których tu użyłem znajdziesz w tej odpowiedzi na Stack Overflow: How do I find all files containing specific text on Linux?
Ten i powyższy przykład zastosowania grep
są opisane w tym, dosyć wyczerpującym, artykule o tej komendzie: Grep Command in Linux (Find Text in Files).
Jak skasować cały folder z podfolderami?
$ rm -rf <folder-do-skasowania>
Parametr r
odpowiada za rekursywność (kasuje podfoldery), dzięki f
nie będziemy pytani o potwierdzenia. Jeżeli chcesz skasować coś na prawdę ważnego powyższe polecenie może zwrócić błąd wynikający z nieodpowiednich uprawnień. Wtedy uruchamiasz je jako root korzystając z sudo
, tj. sudo rm -rf <folder-do-skasowania>
.
Jak zabić proces?
Są dwie drogi – jedna edukacyjna, druga krótka 🙂
W tej pierwszej musisz, po pierwsze, znaleźć proces który chcesz usunąć. Polecam do tego polecenie htop
, lub, jeśli masz uboższą bądź starszą dystrybucję – top
. Oba polecenia wyświetlają pełnoekranowe (ale działające płynnie na zdalnym terminalu) podsumowania wszystkich uruchomionych procesów. Odnajdzie tam w prosty sposób procesy które konsumują najwięcej zasobów – pamięci RAM lub mocy CPU, lub te które działają najdłużej (mają najdłuższy uptime
). Jeżeli chciałbyś raczej polegać na nazwie procesu szukając jego identyfikatora skorzystaj z polecenie ps aux | grep <nazwa-procesu>
. Ma ono podobną składnie do opisywanego wyżej poszukiwania uruchamianych poleceń. Korzystamy z łącznika |
(pipe) oraz komendy grep
. Źródłem dla grep
jest tutaj ps aux
która to komenda wyświetla wszystkie aktywne procesy.
Niezależnie od tego jak odnajdziesz proces którego chcesz się pozbyć – musisz zwrócić uwagę na jego numer identyfikacyjny – oznaczany jako PID w htop
, top
oraz ps
.
Znając PID możesz wywołać polecenie kill. W skrócie – zabić można na wiele sposobów, jeżeli chcesz się z tego doktoryzować polecam na początek How to Kill a Process from the Command Line, w mojej praktyce, w zdecydowanej większości przypadków, chcę wysłać sygnał SIGKILL (do którego przypisany jest numer 9). Pozwala on zakończyć „siłowo” uruchomiony proces. Możesz to zrobić poleceniem kill -9 <PID>
, więc jeżeli ja chcę się pozbyć zawiśniętego Sporify’a zrobię to tak:
$ ps aux | grep spotify
q 11980 0.4 3.3 5921312 549304 ? Sl Sep11 6:13 /usr/share/spotify/spotify
(...)
q 31047 0.0 0.0 15644 1104 pts/0 S+ 22:31 0:00 grep --color=auto spotify
$ kill -9 11980
$ ps aux | grep spotify
q 31053 0.0 0.0 15644 1004 pts/0 S+ 22:31 0:00 grep --color=auto spotify
Na powyższym przykładzie chciałbym zwrócić Twoją uwagę na 2 rzeczy:
- polecenie grep jest również widziane przez ps aux, więc rezultat komendy
ps aux | grep <dowolna-fraza>
to zawsze przynajmniej jeden proces – właśniegrep
. - często aplikacje desktopowe (te uruchamiane w środowiskach graficznych), tak jak Spotify, posiada wiele aktywnych procesów. W moim wypadku ten o najkrótszej nazwie, który zostawiłem w przykładzie, był procesem nadrzędnym. Pozostałe prawdopodobnie odpowiadały za ikonkę na pasku zadań, logowanie, czy inne, wydzielone zadania. Tutaj musisz albo poprawnie zidentyfikować proces nadrzędny, albo…
Teraz wersja krótka. Tak się składa że jest ona również odpowiedzią na drugi punkt powyżej (aplikacje z wieloma procesami).
Możesz je wszystkie zakończyć poleceniem killall -9 <część-nazwy-procesu>
, np. killall -9 spotify
.
Jak przekopiować plik przez SSH?
Popularny scenariusz – masz dostęp do maszyny tylko przez SSH. Żadnego FTP, SFTP, panelu administratora, udziału sieciowego, czy automatyzacji. Jak skopiować na nią lub z niej plik?
Użyj polecenia scp
. W najprostszej wersji jego składni jest to komenda scp <źródło> <destynacja>
. A więc aby skopiować plik na maszynę zdalną:
scp /home/kuba/plik user@ssh-config:/home/kuba/plik-docelowy
Źródłem jest ścieżka lokalna (pełna) pliku który chcesz skopiować, destynacja – URI z uwzględnieniem np. konfiguracji połączenia sieciowego, nazwy użytkownika czy docelowej lokalizacji. Jeżeli chcesz dowiedzieć się jak skonfigurować preset połączenia ssh (a więc host + autentykacja + nazwa użytkownika) przeczytaj mój artykuł Zdalne repozytorium Git na AWS.
Z maszyny zdalnej na lokalną działamy odwrotnie, ale wciąż uruchamiamy scp
z maszyny lokalnej (tj. kopiujemy na zdalną, poprzez wysłanie pliku z maszyny lokalnej, kopiujemy do siebie, poprzez żądanie pliku od maszyny zdalnej). Bardziej symetryczny schemat (tj. kopiujemy na zdalną poprzez wysłanie pliku z maszyny lokalnej, kopiujemy do siebie poprzez wysłanie pliku z maszyny zdalnej) jest mniej efektywny i wymaga dodatkowego połączenia z maszyną zdalną oraz konfigurację połączenia z maszyny zdalnej na lokalną. Do brzegu, z maszyny zdalnej na lokalną kopiujemy uruchamiając to polecenie z maszyny lokalnej:
scp user@ssh-config:/home/kuba/plik /home/kuba/plik-docelowy
Gdzie znajduje się program który uruchamia dana komenda?
Jest to pytanie które warto sobie zadać kiedy coś się zepsuje – upewnij się że uruchamiasz właściwy program, we właściwej wersji. Możesz po prostu nie ogarniać swojej zmiennej środowiskowej PATH
, a może nie jesteś pewna/ien do której z kilku wersji danego programu odnosi się komenda. Ja osobiście często zastanawiam się do której wersji i instancji Pythona w danym środowisku odnosi się komenda python
.
Rozwiązanie? Skorzystaj z which
:
(.env) kuba@local:~/Documents/projekt/a$ which python
/home/kuba/Documents/projekt/a/.env/bin/python
Jak uruchamiać zadanie w określonych odstępach czasu/w określonym harmonogramie?
W skrócie – należy użyć cron
’a. Jest to mechanizm wykorzystywany *nixach pozwalający na uruchamianie zadań w określonych interwałach lub w określonym czasie. BTW, nazwa pochodzi od Chronosa, greko-romańskiej personifikacji czasu.

Swoim cron’em zarządzasz przez plik crontab
, uruchamiając polecenie crontab -e
. Parametr -e
otworzy bieżący crontab
w domyślnym edytorze tekstowym. Namiar na edytor powinien być dostępny w zmiennej środowiskowej VISUAL lub EDITOR, w przeciwnym razie crontab użyje ścieżki /usr/bin/editor
aby odszukać domyślny edytor plików.
Do crontab
dodajesz wpisy (wiersze) o określonej strukturze którą w bardzo ładny sposób definiuje artykuł cron w angielskiej Wikipedii:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
│ │ │ │ │ 7 is also Sunday on some systems)
│ │ │ │ │
│ │ │ │ │
* * * * * <command to execute>
Teraz kilka przykładów tej notacji, za stroną crontab.guru którą bardzo polecam.
Raz na godzinę (a więc reguła brzmi – o każdej zerowej minucie):
0 * * * *
Raz dziennie (a więc o 00:00):
0 0 * * *
W każdy poniedziałek (a konkretnie o 00:00 w poniedziałek):
0 0 * * MON
Więcej przykładów na wspomnianym crontab.guru, a teraz jak wygląda gotowy wiersz crontab
uruchamiające np. backup bazy mongo każdego dnia o 04:00 rano:
0 4 * * * /bin/sh /path/to/backup-mongo.sh
Fin
Mam nadzieję że z czasem uda mi się uzupełnić ten artykuł o kolejne przydatne polecenia w Linuxie, time will tell 😶
P.S.
Zdjęcie tytułowe zrobiłem z ostatniego piętra hotelu „służbowego” Holiday Inn Quingdao Parkview w dzielnicy Chengyang, w mieście Quingdao w Chinach. Gdzieś w okolicach 2015 roku.