View Single Post
Queen of Blades
Jonta's Avatar
DonorCrew
For newbies: Intro til shell, (de)konstruksjon av et skript jeg bruker ~hver dag
For erfarne: Gi kritikk til koden min 'a. (Ligger i første svar. Denne posten ble for lang)

shell er et programmeringsspråk som… altså, det er en måte å fortelle datamaskiner at…

Okay. Åpne terminalen. Sjekk din Linux-distro for hvordan
BSD: Du vet allerede hvordan
macOS: Terminal.app
Windows: Installér nyeste Ubuntu LTS fra Microsoft Store, og start derifra. (snegler forklarer mer lengre ned her

Shock horror: Det finnes flere måter å gjøre det på i macOS og Windows. Hvem skulle trodd.

OK.

Terminalen er åpen.

«Ser skummel ut»

Det går bra. Vi skal ikke gjøre farlige ting. Om du er usikker: Søk opp kommandoen før du taster den inn, så du er sikker på at jeg ikke lurer deg til å slette alle filene dine

Kode

ls
Lister opp filene i den mappa

Kode

ls -alhS
Lister opp skjulte filer også (a), i langt format (l), med størrelsene i menneskeleselig format (h), og sorterer dem etter størrelse (S)

«Cool. Ser litt hacker ut. Så dette er shell?»

Om du vil ha en fisefin definisjon av hva shell er, får du finne en selv

«Andre kommandoer?»

Plenty

Kode

mkdir lærelittshell
Oppretter en mappe som heter… gjett 2 ganger

Kode

cd lærelittshell
Går inn i den mappa

«Men… men ls. Jeg vil vite mer!»

Kode

man ls
For manualen. q for å gå ut igjen.

Eller foreta et nettsøk. Man-pages er ikke så nybegynnervennlige

Kode

touch filami
Oppretter ei fil ved navn…

Kode

file filami
empty ja. Det skal vi gjøre noe med

Kode

vim filami
OIOIOI skummelt! Jeg anbefaler å lære basics i vim. Tar ikke så lang tid som folk gir uttrykk for. Her er en tråd, https://freak.no/forum/showthread.php?t=303799

Kode

vimtutor
gir deg det du trenger

Kode

nano filami
Om du er under 10 år gammel. Shots fired. Du kommer til å bruke tid på å skrive, så det er verdt investeringa. Åpne, lagre, lukke, gå opp/ned/høyre/venstre. Bare fordi vim kan mye mer, betyr det ikke at du trenger å lære alt sammen før du kan bruke det

Uansett hvordan du gjør det, skriv følgende i fila: (vim: Tast i)

Kode

#!/bin/sh
ls -alhS
Og så lagrer og lukker du (vim: Escape-tasten, og så :x Enter (kolon, bokstaven x, begge bør dukke opp nederst på skjermen, trykk Enter)

«Hey, jeg kjenner igjen kommandoen!»

Jepp

Kode

chmod 755 filami
For å gjøre den kjørbar

Kode

./filami
Du kjørte nettopp et shell-skript!

Jepp. Så enkelt er det. Og PC-en din brant ikke opp, og FBI står ikke på døra, og ingen forteller de åpenbare teite vitsene

«Meeere! Meeere!»

OK. Åpne fila igjen

Kode

vim filami
Endre fila ved å legge til ei linje, så den nå ser slik ut:

Kode

#!/bin/sh
ls -alhS
echo "Kake er nammenam"
(Jeg er overbevist om at de fleste vil ha betydelig mer utbytte av å faktisk trykke taztene enn å bare copypaste. At det øker vissheten om at nettopp du også kan gjøre dette)

Lagre, lukk, og kjør, som før

Spytta maskina ut det du trodde den kom til å gjøre? Ei liste over filer, og så ei ny linje med «Kake er nammenam»?

Vi kan altså kjøre flere kommandoer etter hverandre, ved å plassere dem etter hverandre

«Jeg har mer å si om kake enn at det er nammenam altså»

Null problem

Kode

#!/bin/sh
ls -alhS
echo "Kake er nammenam"
echo "Kake er godt"
echo "Kake er topp"
Vi gjentar ordet «Kake» en del her. Faktisk gjentar vi «Kake er ». Vi skriver det 3 ganger. For et ork.

«Det var ikke så mye ork altså. Jeg bare kopierte den første linja, og så…» Neeei. Ork. Og så trenger jeg det til neste eksempel

Kode

#!/bin/sh
ls -alhS
variabelen_min="Kake er"
echo "$variabelen_min nammenam"
echo "$variabelen_min godt"
echo "$variabelen_min topp"
Ikke plassbesparende akkurat.

Kode

#!/bin/sh
ls -alhS
variabelen_min="Kake er, som min bestefar sa før i tiden, da blomstene var gule og ekorn brune og hele verden var dekket av hvite flekker på kartet, "
echo "$variabelen_min nammenam"
echo "$variabelen_min godt"
echo "$variabelen_min topp"
På tide å skrive noe selv altså. I stedet for å bare gjøre som jeg sier. Nå skal du få skrive inn noe, som maskina spytter ut:

Kode

#!/bin/sh
ls -alhS
echo "Hva skal variabelen inneholde?"
read variabelen_min
echo "$variabelen_min nammenam"
echo "$variabelen_min godt"
echo "$variabelen_min topp"
«OK JEG SKJØNNER NÅ JONTA HVOR ER EKSEMPELET FRA VIRKELIGHETEN JEG KJEEEDER MEEEG!»

I vim/(spac)emacs-tråden jeg lenker til over nevnes org-mode.
Jeg bruker det til en tabell for prosjektene mine.
Jeg har mange prosjekter.
236 i tabellen akkurat nå.
Det er mange å holde styr på.
Derfor har jeg en tabell.
«Har du vurdert å bare ikke ha tabellen?»
Ja. Det har jeg. Det funker ikke for hjernen min.
«Men JEG trenger ikke en slik tabell!»
Fint for deg. Finn et annet eksempel fra virkeligheten da.

Her er et minimalt eksempel på tabellen:

Kode

| 1 Total | 2 Name               | 3 Comment                            | 4 Tags                      | 5 Progress | 6 Utility | 7 Fun | 8 Desire | 9 Size | 10 Difficulty |
|---------+----------------------+--------------------------------------+-----------------------------+------------+-----------+-------+----------+--------+---------------|
|      17 | nFF lærer litt shell | Minimalt innhold. Bare få ut en tråd | nff, web, programming, tech |          3 |         6 |     7 |        8 |      4 |             3 |
#+TBLFM: $1=($5+$6+$7+$8-$9-$10)
Overskrifter
Skillelinje
Prosjektlinje
Helt nederst: Kalkulasjon: Jeg legger sammen progress, utility, fun og desire, og trekker fra size og difficulty. Er lik total. Som tabellen sorteres etter (org-table-sort-lines)

Ikke perfekt, men fy så mye flottere enn å ha ingenting.

Et problem dukket opp: Det var distraherende å se alle de andre prosjektene imens jeg tastet inn et nytt et

Løsning:

Et shell-skript som leser prosjektnavn fra ei fil, og så spør meg om kommentar, tags, osv etterhvert. Og så skriver det til en annen fil, så jeg kan copypaste innholdet fra den fila inni org-fila mi. (Kunne skrevet rett til org-fila, men såpass robust er ikke systemet mitt for dette enda. Og elisp, språket man bruker i emacs, er jeg ikke komfortabel med. Enda)

«Weird flex, but okay»

Ja? Hva trenger vi da?

«Eh… skrive?»

Ja. Hva mer?

«Lese fra fila. Og fila sjøl»

Jepp.

Input:

Kode

nFF lærer litt shell
Pluss det brukeren skriver inn

Output:

Kode

| 17 | nFF lærer litt shell | Minimalt innhold. Bare få ut en tråd | nff, web, programming, tech | 3 | 6 | 7 | 8 | 4 | 3 |
(org-mode tar seg av antall mellomrom)

«Org-mode, org-mode, org-mode. Skrev du denne posten i emacs også eller?»

Ja. bbcode-mode

«U r trash»

OK

«jk, ilu»

OK. Klar til å lage en liste over hva vi vil ha?

«Jaaa!»

- inputfil
- outputfil
- Lese brukerinput
- Lese fra inputfila
- Skrive til outputfila

Hva mer?

«Du sa det forstyrret å ha all teksten på skjermen. Kan vi fjerne den mellom hvert spørsmål kanskje?»

Det er som om du er en fiktiv forumbruker fundert opp av meg selv

Det kan vi bruke

Kode

clear
til. Prøv selv.

Kode

ls
Og så

Kode

clear
Ctrl+L går også. Men ikke i et skript. Så vidt jeg vet.

Såh:
- inputfil
- outputfil
- Lese brukerinput
- Lese fra inputfila
- Skrive til outputfila

Lese brukerinput har vi allerede gjort. Og lagret i variabel

Skrive til outputfil er også ganske greit:

Kode

#!/bin/sh
echo "Hva skal variabelen inneholde?"
read variabelen_min </dev/tty
echo $variabelen_min >> outputfila.txt
echo "$variabelen_min nammenam"
echo "$variabelen_min godt"
echo "$variabelen_min topp"
Dobbelpil er å legge til på bunnen av fila. Enkeltpil (>) betyr å overskrive den. Bruk med omhu

Og ja, jeg kvitta meg med ls-en

Da gjenstår bare:

- inputfil
- Lese fra inputfila

Og vi vil ikke bare lese én gang. Vi vil lese hver linje. Så lenge det er linjer

Kode

#!/bin/sh
echo "Hva skal variabelen inneholde?"
read variabelen_min
echo $variabelen_min >> outputfila.txt
echo "$variabelen_min nammenam"
echo "$variabelen_min godt" # Shhhhh. Her. Bak #-en, kan vi gjemme oss. Er en kommentar, skjønner du. Kan skrive hva jeg vil her. Shell-et ser oss ikke. Såeh… hvem er *du* forelska i?
echo "$variabelen_min topp"

while IFS= read -r inputfile_line; do
	echo $inputfile_line "er ei linje"
done < inputfil.txt
While, engelsk «imens». Noe sånt som «imens det fortsatt er linjer å lese, gjør det her:

Boom! Vi har ein inputfil, og vi leste fra den!

Ja, det er et par detaljer i den der while-linja som er litt rare. Hva er IFS= lizm. Og read -r

Men fikser du resten selv?

Skroll opp for de forskjellige feltene jeg vil ha ut. Husk at Total regnes ut i org-fila etterpå

Her er løsningsforslaget mitt. E lov å lurkik:

Antall kodelinjer:
SPOILER ALERT! Vis spoiler
32. Ish


Kode:
SPOILER ALERT! Vis spoiler

Kode

#!/bin/sh

while IFS= read -r inputfile_line; do
  echo Name?
  read name </dev/tty
  clear
  echo Comment?
  read comment </dev/tty
  clear
  echo Tags?
  read tags </dev/tty
  clear
  echo Progress?
  read progress </dev/tty
  clear
  echo Utility?
  read utility </dev/tty
  clear
  echo Fun?
  read fun </dev/tty
  clear
  echo Desire?
  read desire </dev/tty
  clear
  echo Size?
  read size </dev/tty
  clear
  echo Difficulty?
  read difficulty </dev/tty
  clear
  echo "| 0 | $name | $comment | $tags | $progress | $utility | $fun | $desire | $size | $difficulty |" >> outputfila.txt
done < inputfil.txt


shellcheck er et fint verktøy
#bash på Freenode ser ut til å kunne sakene sine (Kan være strenge. Vit hvordan man stiller spørsmål på internett)
https://mywiki.wooledge.org

Jeg har foretatt forbedringer såklart. Kanskje jeg går gjennom dem én og én senere i tråden

Om du vil prøve deg uten å se på koden jeg bruker nå er dette ei cirka komplett liste:
SPOILER ALERT! Vis spoiler

- Progressbar
- shellcheck for å forebedre ting (printf > echo)
- Kan ta et argument som inputfil
- outputfile har timestamps i filnavnet
- Hoppe over prosjekter
- Markere prosjekt som gjort
- En del av det i en funksjon
- Ha det-hilsen
Sist endret av Jonta; 23. september 2019 kl. 19:13. Grunn: Lenker til snegler sin post for Windows-brukere