U ovoj lekciji ćemo proći kroz nekoliko načina pomoću kojih možete da poboljšate vaš rad u korišćenju shell-a. Sa shell-om radimo već neko vrijeme, ali smo se najviše fokusirali na izvršavanje različitih komandi. Sada ćemo vidjeti kako da pokrenemo nekoliko procesa u isto vrijeme dok ih pratimo, kako da zaustavimo ili pauziramo specifični proces i kako da podesimo proces da radi u pozadini.
Takođe ćemo naučiti različite načine da poboljšate vaš shell i druge alate, definisanjem pseudonima i konfigurisanjem istih pomoću dotfiles. I jedno i drugo će vam uštedjeti vrijeme, npr. korišćenjem istih konfiguracija za sve vaše mašine bez potrebe da pišete duge komande. Vidjećemo i kako da radimo sa udaljenim mašinama koristeći SSH.
Kontrola posla
U nekim slučajevima ćete morati da prekinete posao u toku izvršavanja, npr. ukoliko je komandi potrebno previše vremena da bi se izvršila (kao npr.
1
nalaženje1
Ctrl-CUbijanje procesa
Vaš shell koristi UNIX komunikacioni mehanizam koji se zove signal za prosleđivanje informacija procesu. Kada proces primi signal, on zaustavlja svoje izvršavanje, bavi se signalom i potencijalno mijenja tok izvršenja na osnovu informacija koje je signal isporučio. Iz ovih razloga, signali su ono što zaustavlja softver.
U našem slučaju, kada kucamo
1
Ctrl-C1
SIGINTEvo minimalističkog primjera Python programa koji snimi
1
SIGINT1
SIGQUIT1
Ctrl-\1 2 3 4 5 6 7 8 9 10 11 12#!/usr/bin/env python import signal, time def handler(signum, time): print("\nI got a SIGINT, but I am not stopping") signal.signal(signal.SIGINT, handler) i = 0 while True: time.sleep(.1) print("\r{}".format(i), end="") i += 1
Evo šta se dešava ukoliko unesemo
1
SIGINT1
SIGQUIT1
^1
Ctrl1 2 3 4 5 6$ python sigint.py 24^C I got a SIGINT, but I am not stopping 26^C I got a SIGINT, but I am not stopping 30^\[1] 39913 quit python sigint.py
Dok su
1
SIGINT1
SIGQUIT1
SIGTERM1
kill -TERM <PID>Pauziranje i stavljanje procesa u pozadinu
Signali mogu raditi i druge stvari mimo zaustavljanja procesa. Na primer,
1
SIGSTOP1
Ctrl-Z1
SIGTSTP1
SIGSTOPZatim možemo nastaviti pauzirani posao koji se nalazi u prvom planu ili u pozadini koristeći, zavisno od toga, fg ili bg.
Jobs komanda izlistava nezavršene poslove koji su povezani sa trenutnom sesijom terminala. Možete referencirati te poslove koristeći njihov pid (možete koristiti pgrep da to saznate). Još više intuitivnije, možete referencirati proces koristeći simbol procenta i njegov broj zadatka (prikazan kao
1
jobs1
$!Dodatna stvar koju je potrebno znati jeste da
1
&Da bi prebacili u pozadinu program koji je u toku možete odraditi
1
Ctrl-Z1
bg1
SIGHUP1
SIGHUP1
disownIspod je jednostavna sesija koja prikazuje neke od tih koncepata.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41$ sleep 1000 ^Z [1] + 18653 suspended sleep 1000 $ nohup sleep 2000 & [2] 18745 appending output to nohup.out $ jobs [1] + suspended sleep 1000 [2] - running nohup sleep 2000 $ bg %1 [1] - 18653 continued sleep 1000 $ jobs [1] - running sleep 1000 [2] + running nohup sleep 2000 $ kill -STOP %1 [1] + 18653 suspended (signal) sleep 1000 $ jobs [1] + suspended (signal) sleep 1000 [2] - running nohup sleep 2000 $ kill -SIGHUP %1 [1] + 18653 hangup sleep 1000 $ jobs [2] + running nohup sleep 2000 $ kill -SIGHUP %2 $ jobs [2] + running nohup sleep 2000 $ kill %2 [2] + 18745 terminated nohup sleep 2000 $ jobs
Specijalni signal je
1
SIGKILLMožete naučiti više o ovim i drugim signalima ovdje ili kucanjem man signal ili
1
kill -tMultiplexeri Terminala
Kada koristite interfejs komandne linije obično ćete željeti da pokrenete više stvari odjednom. Na primer, možda ćete željeti da pokrenete vaš editor i vaš program jedno pored drugog. Iako ovo može biti ostvareno otvaranjem novog prozora terminala, korišćenje multiplexera terminala je svestranije rešenje.
Multiplexeri terminala kao što je tmux vam pružaju mogućnost multiplexa terminala prozora koristeći panes i tabove tako da možete imati interakciju sa više shell sesija. Još više, multiplexeri terminala vam dopuštaju da odvojite trenutnu sesiju terminala i da se prikačite na nju u nekom kasnijem trenutku. Ovo može mnogo popraviti vaše iskustvo kada radite sa udaljenim mašinama jer izbjegava upotrebu
1
nohupNajpopularniji multiplexer terminala ovih dana je tmux.
1
tmux1
tmux1
<C-b> x1
Ctrl+b1
Ctrl+b1
x1
tmux- Sesije - Sesija je nezavisni radni prostor sa jednim ili više prozora
- započinje novu sesiju
1tmux - je započinje sa tim nazivom
1tmux new -s NAME - izlistava trenutnu sesiju
1tmux ls - U okviru kucanje
1tmuxodvaja trenutnu sesiju1<C-b> d - pridodaje poslednju sesiju. Možete da koristite
1tmux aflag da označite koju1-t
- Windows - Ekvivalent tabovima u editoru ili pretraživaču - vizuelno odvaja dio iste sesije
- Kreira novi prozor. Da ga zatvorite možete zaustaviti shell koristeći
1<C-b> c1<C-d> - Ide do N th prozora. Imajte u vidu da su numerisani
1<C-b> N - Ide do prethodnog prozora
1<C-b> p - Ide do sledećeg prozora
1<C-b> n - Mijenja ime trenutnog prozora
1<C-b> , - Izlistava trenutni prozor
1<C-b> w
- Panes - Kao i vim splits, panes vam dopuštaju da imate više shell-ova na istom displeju.
- Dijeli trenutni pane horizontalno
1<C-b> " - Dijeli trenutni pane vertikalno
1<C-b> % - pomjera pane u zadati pravac. Pravac ovdje označava tastere sa strelicama.
1<C-b> <direction> - Uključuje zoom za trenutni pane
1<C-b> z - Započinje pomicanje unazad. Zatim možete pritisnuti
1<C-b> [da započnete selekciju i1<space>da kopirate tu selekciju.1<enter> - Kruži kroz pane uređenje.
1<C-b> <space>
Za dalje čitanje, ovdje je kratki tutorijal na
1
tmux1
screenPseudonimi
Može biti zamorno kucanje dugih komandi koje uključuju mnoge flagove ili opširne opcije. Iz ovog razloga, većina shell-ova podržava pseudonime. Shell pseudonim je kratka forma neke komande koju će vaš shell automatski zamijeniti za vas. Na primer, psuedonim u bash-u ima sledeću strukturu:
1alias alias_name="command_to_alias arg1 arg2"
Imajte u vidu da nema razmaka okolo znaka jednako
1
=Pseudonimi imaju mnoge pogodne funkcije:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28# Make shorthands for common flags alias ll="ls -lh" # Save a lot of typing for common commands alias gs="git status" alias gc="git commit" alias v="vim" # Save you from mistyping alias sl=ls # Overwrite existing commands for better defaults alias mv="mv -i" # -i prompts before overwrite alias mkdir="mkdir -p" # -p make parent dirs as needed alias df="df -h" # -h prints human readable format # Alias can be composed alias la="ls -A" alias lla="la -l" # To ignore an alias run it prepended with \ \ls # Or disable an alias altogether with unalias unalias la # To get an alias definition just call it with alias alias ll # Will print ll='ls -lh'
Imajte u vidu da pseudonimi nisu trajni u shell sesiji po default-u. Da bi neki pseudonim bio trajan morate ih uključiti u shell startup datoteci, kao što je
1
.bashrc1
.zshrcDotfiles
Mnogi programi se podešavaju koristeći datoteke sa čistim tekstom poznate kao dotfiles (jer naziv datoteke počinje sa
1
.1
~/.vimrc1
lsShell-ovi su jedan primjer programa koji se podešavaju preko takvih fajlova. Prilikom pokretanja, vaš shell će pročitati mnoge datoteke da bi se učitala njegova podešavanja. Zavisno od shell-a, bilo da pokrećete login i/ili interakciju, čitav proces može biti veoma kompleksan. Ovo je odličan resurs na ovu temu.
Za
1
bash1
.bashrc1
.bash_profile1
PATH1
export PATH="$PATH:/path/to/program/bin"Neki drugi primjeri alata koji mogu biti podešeni kroz dotfiles su:
1bash - ~/.bashrc, ~/.bash_profile1git - ~/.gitconfig- -
1vimand the1~/.vimrc1~/.vim folder 1ssh - ~/.ssh/config1tmux - ~/.tmux.conf
Kako da organizujete vaše dotfiles? Oni bi trebali da budu u njihovom posebnom folderu, ispod kontrole verzije, i symlinked na mjesto koristeći script. Ovo ima sledeće benefite:
- Laka instalacija: ukoliko se ulogujete na novu mašinu, potvrđivanje vaših podešavanja će trajati samo oko minut.
- Prenosivost: Vaši alati će raditi na isti način svuda.
- Sinhronizacija: Možete da ažurirate vaše dotfiles bilo gdje i da svi oni budu sinhronizovani.
- Praćenje promjena: Vjerovatno ćete kroz vašu čitavu programersku karijeru održavati vaše dotfiles, i jako je dobro imati kontrolu istorije za projekte koji će duže trajati.
Šta bi trebali da stavite u dotfiles? Možete učiti o podešavanju vaših alata čitanjem online dokumentacije ili man pages. Drugi dobar način jeste pretraživanje interneta za blog postove o specifičnim programima, gdje će vam autori iznijeti njihove preference podešavanja. Još jedan način da učite o podešavanjima jeste pregledanjem dotfiles drugih ljudi: možete pronaći gomilu dotfiles repositories na Githubu - pogledajte najpopularnije ovdje (Savjetujemo vam da ne kopirate na slijepo podešavanja). Ovdje je još jedan dobar resurs na ovu temu.
Svi instruktori ovih lekcija imaju njihove dotfiles koji su svima dostupni na Github-u: Anish, Jon, Jose.
Prenosivost
Čest problem sa dotfiles jeste što podešavanja možda neće raditi u radu sa nekoliko mašina, npr. ukoliko imaju različite operativne sisteme ili shell-ove. Ponekad takođe želite da se podešavanja primjenjuju samo na mašini na kojoj u tom trenutku radite.
Postoje česti trikovi da vam to olakšaju. Ukoliko to datoteka sa podešavanjima podržava, koristite ekvivalent if izjava da bi na mašini primjenili specifična podešavanja. Na primer, vaš shell može imati nešto kao što je:
1 2 3 4 5 6 7if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi # Check before using shell-specific features if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi # You can also make it machine-specific if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi
Ukoliko fajl sa podešavanjima to podržava, koristite includes. Na primer,
1
~/.gitconfig1 2[include] path = ~/.gitconfig_local
Onda na svakoj mašini,
1
~/.gitconfig_localOva ideja je takođe korisna ako želite da različiti programi dijele ista podešavanja. Na primer, ukoliko želite da i
1
bash1
zsh1
.aliases1 2 3 4# Test if ~/.aliases exists and source it if [ -f ~/.aliases ]; then source ~/.aliases fi
Udaljene mašine
Kod programera je postalo često da koriste udaljene servere u njihovom svakodnevnom životu. Ukoliko morate da koristite udaljene servere da bi razvili backend software ili vam je potreban server sa visokim računarskim sposobnostima, na kraju ćete koristiti Secure Shell (SSH). Kao i za većinu alata koje smo prešli, SSH je veoma podesiv i vrijedan je učenja.
Da izvršite komandu
1
ssh1ssh [email protected]
Ovdje pokušavamo da ssh kao korisnik
1
foo1
bar.mit.edu1
bar.mit.edu1
ssh barIzvršavanje komandi
Funkcija
1
ssh1
ssh foobar@server ls1
ls1
ssh foobar@server ls | grep PATTERN1
ls1
ls | ssh foobar@server grep PATTERN1
lsSSH ključevi
Autentikacija na bazi ključeva koristi kriptografiju javnog ključa kako bi dokazala serveru da klijent posjeduje tajni privatni ključ bez otkrivanja ključa. Na ovaj način ne morate ponovo da unosite password svaki put. Ipak, privatni ključ (često kao
1
~/.ssh/id_rsa1
~/.ssh/id_ed25519Generisanje ključeva
Da bi generisali par možete izvršiti ssh-keygen.
1ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519
Trebali bi da izaberete lozinku, da bi izbjegli da neko ko dođe do vašeg privatnog ključa ima autorizovani pristup serverima. Koristite ssh-agent ili gpg-agent tako da ne morate da kucate vašu lozinku svaki put.
Ako ste ikada podešavali pushing na GitHub koristeći SSH ključ, onda ste vjerovatno napravili korake koji su navedeni ovdje i već imate validan par ključeva. Da bi provjerili da li imate lozinku i da je potvrdite možete izvršiti
1
ssh-keygen -y -f /path/to/keyAutentikacija bazirana na ključevima
1
ssh1
.ssh/authorized_keys1cat .ssh/id_ed25519.pub | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'
Jednostavnije rešenje može biti postignuto sa
1
ssh-copy-id1ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote
Kopiranje datoteka preko SSH-a
Postoji mnogo načina da kopirate datoteke preko SSH:
- , najlakše je koristiti
1ssh+teeizvršenje komande i STDIN input koristeći1ssh. Sjetite se da tee ispisuje output iz STDIN u datoteku.1cat localfile | ssh remote_server tee serverfile - scp kada kopirate veliku količinu datoteka/direktorijuma, sigurna copy komanda je pogodnija jer se lakše može kretati kroz paths. Sintaksa je
1scp.1scp path/to/local_file remote_host:path/to/remote_file - rsync je poboljšanje u odnosu na zbog detektovanja identičnih datoteka lokalno i udaljeno, i sprečavanja njihovog ponovnog kopiranja. Takođe omogućava bolju kontrolu nad symlinks, dozvolama i ima dodatne funkicje kao što su
1scpflag koji može nastaviti iz prethodno prekinute kopije.1--partialima sličnu sintaksu kao i1rsync.1scp
Prosleđivanje port-a
U mnogim scenarijima ćete naići na software koji sluša određene portove na mašini. Kada se ovo desi na vašoj lokalnoj mašini možete kucati
1
localhost:PORT1
127.0.0.1:PORTOvo se naziva prosleđivanje port-a i dolazi u dvije varijatnte: Local Port Forwarding and Remote Port Forwarding (pogledajte slike za više detalja, slike su sa ovog StackOverflow posta.
Local Port Forwarding

Remote Port Forwarding

Najčešći scenario je local port forwarding, gdje service na udaljenoj mašini sluša port a vi želite da povežete port na lokalnoj mašini da biste ga proslijedili na udaljeni port. Na primer, ukoliko mi izvršimo
1
jupyter notebook1
88881
99991
ssh -L 9999:localhost:8888 foobar@remote_server1
locahost:9999SSH podešavanja
Prošli smo mnoge argumente koje možemo da proslijedimo. Izazovna alternativa jeste da se kreira shell pseudonim koji izgleda ovako:
1alias my_server="ssh -i ~/.id_ed25519 --port 2222 -L 9999:localhost:8888 foobar@remote_server
Ipak, postoji bolja alternativa koristeći
1
~/.ssh/config1 2 3 4 5 6 7 8 9 10Host vm User foobar HostName 172.16.174.141 Port 2222 IdentityFile ~/.ssh/id_ed25519 LocalForward 9999 localhost:8888 # Configs can also take wildcards Host *.mit.edu User foobaz
Dodatna prednost korišćenja
1
~/.ssh/config1
scp1
rsync1
moshImajte na umu da
1
~/.ssh/configKonfiguracija na serveru je obično označena u
1
/etc/ssh/sshd_configOstalo
Čest problem prilikom povezivanja sa udaljenim serverom su prekidi veze zbog isključivanja/spavanja računara ili promjene mreže. Štaviše, može postati prilično frustrirajuće ukoliko neko ima značajan lag korišćenjem ssh-a. Mosh, mobilni shell, poboljšanje je u odnosu na ssh, omogućuje roming veze, povremeno povezivanje i pružanje inteligentnog lokalnog echo-a.
Ponekad je prikladno montirati ga u udaljenu datoteku. sshfs može montirati datoteku na udaljeni server lokalno, a zatim možete koristiti lokalni editor.
Shells & Frameworks
Tokom lekcije o shell alatima i scriptingu, prošli smo
1
bashNa primer,
1
zsh1
bash- Pametniji globbing,
1** - Inline globbing/wildcard ekspanzija
- Pravopisna korekcija
- Bolje popunjavanje/odabir tabova
- Path ekspanzija (će se proširit kao
1cd /u/lo/b)1/usr/local/bin
Frameworks mogu poboljšati shell takođe. Neki popularni opšti frameworks su prezto ili ohmyz, i manji koji se fokusiraju na specifične funkcije kao što su zsh-syntax-highlighting ili zsh-history-substring-search. Shell kao što je fish uključuje mnoge user-friendly funkcije defaultno. Neke od tih funkcija uključuju
- Pravi prompt
- Označavanje sintaksnih komandi
- Pretraga substring istorije
- Dovršavanje flagova na bazi manpage-a
- Pametnije auto dovršavanje
- Prompt teme
Treba da imate na umu da kada koristite ove frameworke, da oni mogu usporiti vaš shell, posebno ukoliko kod koji oni izvršavaju nije optimizovan ili se radi o previše koda. Uvijek ga možete profilisati ili omogućiti funkcije koje ne koristite često ili ih ne vrednujete u odnosu na brzinu.
Emulatori Terminala
Zajedno sa podešavanjem vašeg shella, vrijedi uložiti malo vremena da bi izabrali emulator terminala i njegova podešavanja. Postoji mnogo emulatora terminala (ovdje je poređenje
S obzirom na to da možete provoditi stotine ili hiljade sati u vašem terminalu, isplati se da pogledate njegova podešavanja. Neki od tih stvari koje bi željeli da podesite u vašem terminalu uključuju:
- Izbor fonta
- Schemu boja
- Prečice na tastaturi
- Tab/Pane podrška
- Scrollback podešavanja
- Performanse (Neki noviji terminali kao što su Alacritty, ili kitty nude ubrzanje GPU-a).
Vježbe
Kontrola poslova
-
Iz onoga što smo vidjeli, možemo koristiti neke
komande da dobijemo proces ID posla i zatim da ih ugasimo, ali postoji bolji način da to odradimo. Započnite1ps aux | grepposao u terminalu, prebacite ga u pozadinu sa1sleep 10000i nastavite izvršavanje sa1Ctrl-Z. Sada koristite pgrep da saznate ID procesa i pkill da bi ga ugasili bez toga da sami kucate ID procesa.(Nagovještaj: koristite1bgflag).1-af -
Recimo da ne želite da započnete proces dok se drugi ne završi, na koji način bi to riješili? U ovoj vježbi naš proces ograničavanja će uvijek biti
. Jedan način da ovo ostvarite jeste da koristite wait komandu. Pokušajte da pokrenete sleep komandu i da1sleep 60 &sačeka dok se proces u pozadini završi.1ls
Ipak, ovakva strategija neće uspjeti ukoliko započnemo u drugoj bash sesiji, budući da
1
wait1
kill1
kill -01
pidwait1
sleepMultiplexeri Terminala
- Pratite ovaj tutorijal i naučite kako da uradite neka osnovna podešavanja prateći ove korake.
1tmux
Pseudonimi
- Kreirajte pseudonim koji se pretvara u
1dckada ga pogrešno napišete.1cd - Pokrenite da bi dobili vaših top 10 komandi koje najčešće koristite i razmislite da napišete kraće pseudonime za njih. Napomena: ovo radi za Bash; Ukoliko koristite ZSH, koristite
1history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10umjesto samo1history 1.1history
Dotfiles
Hajde da vas ubrzamo sa dotfiles.
- Kreirajte folder za vaše dotfiles i postavite kontrolu verzije.
- Dodajte konfiguraciju za bar jedan folder, npr. vaš shell, sa nekim podešavanjem (za početak, može biti nešto tako jednostavno kao što je podešavanje vašeg shell prompta stavljajući ).
1$PS1 - Podesite način za bržu instalaciju vaših dotfiles (i bez ručnog truda) na novoj mašini. Ovo može biti jednostavno kao shell skripta koja poziva za svaku datoteku, ili možete koristiti specijalno sredstvo.
1ln -s - Testirajte vašu instalacionu skriptu na svježoj virtualnoj mašini
- Prebacite sve svoje trenutne konfiguracije alata u skladište vaših dotfiles
- Objavite vaše dotfiles na GitHubu.
Udaljene mašine
Instalirajte Linux virtualnu mašinu (ili koristite već postojeću) za ovu vježbu. Ukoliko vam nisu poznate virtualne mašine pogledajte ovaj tutorijal da bi je instalirali.
- Idite na i provjerite da li imate par SSH ključeva tu. Ukoliko nemate, generišite ih sa
1~/.ssh/. Preporučuje se da koristite password i1ssh-keygen -o -a 100 -t ed25519, više informacija ovdje.1ssh-agent - Editujte da ima unos kakav slijedi
1.ssh/config
1 2 3 4 5Host vm User username_goes_here HostName ip_goes_here IdentityFile ~/.ssh/id_ed25519 LocalForward 9999 localhost:8888
- Koristite da bi kopirali vaš ssh ključ na serveru.
1ssh-copy-id vm - Pokrenite webserver na vašoj VM izvršavanjem . Pristupite VM webserveru krećući se do
1python -m http.server 8888u vašoj mašini.1http://localhost:9999 - Uredite vaš SSH server config sa i onemogućite autentikaciju passworda editovanjem vrijednosti
1sudo vim /etc/ssh/sshd_config. Onemogućite root login uređivanjem vrijednosti1PasswordAuthentication. Restartujte1PermitRootLoginservise sa1ssh. Pokušajte ssh ponovo.1sudo service sshd restart - (Izazov) Instalirajte mosh u VM i uspostavite konekciju. Zatim prekinite konekciju network adaptera sa serverom/VM. Da li se mosh može propisno oporaviti od toga?
- (Izazov) Pogledajte šta i
1-Nflagovi rade u1-fi smislite koju komandu da izvršite da bi postigli port forwarding u pozadini.1ssh
