Min första bash-kodning. Kritik önskas

Permalänk
Medlem

Min första bash-kodning. Kritik önskas

God kväll.

Är ny inom Linux-världen och har märkt att det kan vara rätt så tidskrävande att hålla på och installera sina favoritprogram och tjänster efter en ren installation av operativsystemet, så jag skapade en liten bash-fil. När man kör filen i terminalen, så installerar den de program och tjänster som jag anser är nödvändiga för främst mitt egna bruk. Är helt ny inom bash-kodningsvärlden (detta är mitt första projekt), så jag skulle väldigt gärna få veta vad ni tycker om den.

De kommandon som är listade i filen är dock inte universala (funkar endast i de system som stödjer apt, till exempel Ubuntu). Har valt att lägga ut projektet på GitHub för att låta andra förbättra den och göra den mer robust.

https://github.com/edgren/uuc

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
Hedersmedlem

Hej!

Om du inte redan känner till det kan jag slå ett slag för ShellCheck! Det hittar många "fel" som är lätta att göra i bash-script och de få gångerna jag skriver något i bash så är denna alltid väldigt värdefull för att hitta fel.

Hinner dessvärre inte titta något på ditt projekt just nu mer än att bara tipsa om detta verktyg.

Permalänk
Medlem

Min första tanke är, "varför göra något som det finns utmärkta verktyg för". Min andra tanke är då givetvis "för att bekanta sig med bash", och det är givetvis en utmärkt anledning, men räkna inte med att du kommer att få några stora mängder besök på github, och än mindre någon hjälp med utvecklingen av något som gjorts hundratals, om inte tusentals, gånger.

Så, gällande kodkvalitet: gör inte en sak flera gånger om du kan göra den en gång. Skapa funktioner. Din kod skulle utan tvekan kunna bantas ner till under hundra rader (spontan gissning, troligen än mindre).

Gällande lösning av det faktiska problemet: kolla in de orkestreringsverktyg som finns. Min rekommendation är Ansible då det är lätt att komma in i, även för den som inte är så van i Linux och kräver i princip inga programmeringskunskaper för att börja med. Salt är också ett trevligt verktyg, men har en halvt omvänd approach som kan te sig lite udda att vänja sig vid och kräver server-klient-uppsättning vilket i en hemmiljö ofta är onödigt komplext.
Puppet och Chef är ett par andra alternativ, men som sagt, börja med Ansible.

Visa signatur

Desktop: AMD 3950X, 64 GB RAM, Nvidia 4070 ... (Windows 11)
Serverdesktop: AMD 5600G, 64 GB RAM (Proxmox)
Labbmiljö: Supermicro SC825 X9DRi-F 2xE5-2667v2 64GB RAM
Kamera: Canon R5, Canon RF 100-500, Laowa 100mm f/2.8, Canon RF 24-70 f/2,8

Permalänk
Medlem
Skrivet av pv2b:

Hej!

Om du inte redan känner till det kan jag slå ett slag för ShellCheck! Det hittar många "fel" som är lätta att göra i bash-script och de få gångerna jag skriver något i bash så är denna alltid väldigt värdefull för att hitta fel.

Hinner dessvärre inte titta något på ditt projekt just nu mer än att bara tipsa om detta verktyg.

ShellCheck var en fin skapelse, måste jag säga Man tackar för den. Har korrigerat två fel som ShellCheck visade.

Skrivet av Crazy Ferret:

Min första tanke är, "varför göra något som det finns utmärkta verktyg för". Min andra tanke är då givetvis "för att bekanta sig med bash", och det är givetvis en utmärkt anledning, men räkna inte med att du kommer att få några stora mängder besök på github, och än mindre någon hjälp med utvecklingen av något som gjorts hundratals, om inte tusentals, gånger.

Så, gällande kodkvalitet: gör inte en sak flera gånger om du kan göra den en gång. Skapa funktioner. Din kod skulle utan tvekan kunna bantas ner till under hundra rader (spontan gissning, troligen än mindre).

Gällande lösning av det faktiska problemet: kolla in de orkestreringsverktyg som finns. Min rekommendation är Ansible då det är lätt att komma in i, även för den som inte är så van i Linux och kräver i princip inga programmeringskunskaper för att börja med. Salt är också ett trevligt verktyg, men har en halvt omvänd approach som kan te sig lite udda att vänja sig vid och kräver server-klient-uppsättning vilket i en hemmiljö ofta är onödigt komplext.
Puppet och Chef är ett par andra alternativ, men som sagt, börja med Ansible.

Mjo. Tänkte också på att det jag håller på med har gjorts oräknliga gånger. Men oerhört mycket har redan gjorts nu för tiden, så det är ibland svårt att göra något som inte har gjorts. Dock är den bash-filen främst framtagen till mina egna behov, så att jag kan snabbt och enkelt komma igång efter en ren installation av någon Linux-dist.

Hm. Ja, funktioner kan vara något faktiskt. FÅr ta en titt på det. Tack för tipset

Tack för tipset. Ska kika på dem vid tillfälle.

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
99:e percentilen
Skrivet av Airikr:

Är ny inom Linux-världen och har märkt att det kan vara rätt så tidskrävande att hålla på och installera sina favoritprogram och tjänster efter en ren installation av operativsystemet, så jag skapade en liten bash-fil. När man kör filen i terminalen, så installerar den de program och tjänster som jag anser är nödvändiga för främst mitt egna bruk.

Måste bara tipsa om NixOS, som är designat från grunden för att lösa detta problem. Man har en fil, /etc/nixos/configuration.nix, som beskriver hela systemet, inklusive applikationer, bibliotek, användare, filsystem, skrivbordsmiljö, nätverksinställningar etc.

Rekommenderar hyfsad vana med Linux och CLI innan man ger sig på NixOS dock. Det är inte alltid så enkelt att lösa problem med hjälp av Google som det ofta är med t ex Ubuntu.

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Medlem
Skrivet av Alling:

Måste bara tipsa om NixOS, som är designat från grunden för att lösa detta problem. Man har en fil, /etc/nixos/configuration.nix, som beskriver hela systemet, inklusive applikationer, bibliotek, användare, filsystem, skrivbordsmiljö, nätverksinställningar etc.

Rekommenderar hyfsad vana med Linux och CLI innan man ger sig på NixOS dock. Det är inte alltid så enkelt att lösa problem med hjälp av Google som det ofta är med t ex Ubuntu.

Tack för tipset. Är dock än så länge supernöjd med elementary OS

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
Medlem

Kanske är värt att avsluta med en: sudo apt-get autoremove

för att städa upp lite extra paket som kan ha dykt upp under installation

Permalänk
Medlem
Skrivet av AfterShock:

Kanske är värt att avsluta med en: sudo apt-get autoremove

för att städa upp lite extra paket som kan ha dykt upp under installation

Smart! Tack Har publicerat ändringen.

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
Hedersmedlem

Hej, @Airikr. Nu har jag hunnit gå igenom din kod.

För det första håller jag med @CrazyFerret att det du gör i ditt script är en perfekt match för Ansible, och att många av de synpunkterna jag kommer med här kommer lösas automatiskt om du skriver det hela som en Ansible-playbook istället.

Men nu är ju syftet att lära sig och öva på shell-scriptning och få feedback på detta snarare än att lösa ett specifikt problem, så vi släpper Ansible nu och fokuserar på scriptet.

Du lägger in ett onödigt beroende på sudo. Det finns många sätt att bli root på en Linuxburk, och sudo är bara ett av dessa sätt. Om du t.ex. redan är root så är det helt onödigt att anropa sudo. Du förlitar dig också på sudo:s beteende att inte be om lösenord varje gång man kör sudo, detta kan vara konfigurerat annorlunda och det kan sluta med att användaren får mata in sitt eget lösenord flera gånger. Bättre lösning är att ta bort alla anrop till "sudo" och istället i början av scriptet kolla om du är root, och förvänta dig att användaren själv istället kör hela scriptet som root.

Du utför noll felhantering i själva scriptet. Om t.ex. en apt-get update misslyckas av någon anledning kommer scriptet bara gå vidare till nästa steg, och eventuellt felmeddelande kommer bara dränkas av en massa rader av text från nästa kommando etc. Här bör du kolla att ett kommando lyckats köra innan du kör nästa.

Ditt script är inte effektivt med att ställa alla frågor först. Istället för att ställa en fråga om "vill du göra A", sedan gå och göra A, sedan gå tillbaka och fråga om du ska göra B, och sedan göra det. Mer effektivt vore att börja med att fråga vad användaren vill i början, och sedan göra allt i ett svep. Då kan användaren effektivt svara på alla frågorna och sedan koka en kopp kaffe, och komma tillbaks till en färdig installation.

Ditt script anropar t.ex. apt-get install så att det ställer frågor. Samma som ovan, när apt-get install kör så kommer den fråga om du vill installera paketen i fråga. Kanske inte önskvärt i ett automatiskt script. Kolla om apt-get har en flagga för att skippa denna frågan, och även andra interaktiva frågor.

Om användaren skriver fel på ett svar kraschar scriptet. Om användaren skriver till t.ex. "Hej" som svar på en ja/nej fråga så bör scriptet fråga igen, inte bara avsluta scriptet.

Scriptet i sig är inte scriptbart. Istället för en massa ja/nej-frågor interkativt, fundera på att lägga på lite flaggor till scriptet istället, eller iaf ha den möjligheten. Då kan du lätt skriva ett oneliner-script som installerar allt du vill ha precis som du vill ha det istället för att svara på en massa j/n-frågor.

Ditt script anropar apt-get alldeles för många gånger i onödan. Du kör en apt-get update många gånger i scriptet vilket bara tar en massa tid i onödan, sen kör du apt-get install flera gånger med olika listor på paket. Mycket smartare att bygga en lista på paket först och sedan installera allt på en gång. Men det värsta är ändå nästan längst ner i scriptet:

sudo apt-get --purge remove chromium sudo apt-get --purge remove chromium-browser sudo apt-get --purge remove chrome sudo apt-get --purge remove google-chrome sudo apt-get --purge remove firefox sudo apt-get --purge remove mozilla sudo apt-get --purge remove iceweasel sudo apt-get --purge remove seamonkey sudo apt-get --purge remove lynx sudo apt-get --purge remove www-browser sudo apt-get --purge remove links sudo apt-get --purge remove links2 sudo apt-get --purge remove w3m sudo apt-get --purge remove elinks sudo apt-get --purge remove epiphany sudo apt-get --purge remove konqueror

Det här bör bara vara en rad.

Permalänk
Medlem
Skrivet av pv2b:

Hej, @edgren. Nu har jag hunnit gå igenom din kod.

För det första håller jag med @CrazyFerret att det du gör i ditt script är en perfekt match för Ansible, och att många av de synpunkterna jag kommer med här kommer lösas automatiskt om du skriver det hela som en Ansible-playbook istället.

Men nu är ju syftet att lära sig och öva på shell-scriptning och få feedback på detta snarare än att lösa ett specifikt problem, så vi släpper Ansible nu och fokuserar på scriptet.

Hej och tack för inlägget

Skrivet av pv2b:

Du lägger in ett onödigt beroende på sudo. Det finns många sätt att bli root på en Linuxburk, och sudo är bara ett av dessa sätt. Om du t.ex. redan är root så är det helt onödigt att anropa sudo. Du förlitar dig också på sudo:s beteende att inte be om lösenord varje gång man kör sudo, detta kan vara konfigurerat annorlunda och det kan sluta med att användaren får mata in sitt eget lösenord flera gånger. Bättre lösning är att ta bort alla anrop till "sudo" och istället i början av scriptet kolla om du är root, och förvänta dig att användaren själv istället kör hela scriptet som root.

Ok. Så när jag väl har kört bash-filen med sudo (sudo sh filen.sh) så behöver jag alltså inte börja apt-get med sudo? Den processen är redan klar?

Skrivet av pv2b:

Du utför noll felhantering i själva scriptet. Om t.ex. en apt-get update misslyckas av någon anledning kommer scriptet bara gå vidare till nästa steg, och eventuellt felmeddelande kommer bara dränkas av en massa rader av text från nästa kommando etc. Här bör du kolla att ett kommando lyckats köra innan du kör nästa.

Nä. Vet Vet ej hur man ska skapa felhantering i en bash-fil, men jag ska söka runt på nätet om det vid tillfälle. Fokuserar i första hand på att filen ska fungera som den ska först (med andra ord, hämtar allt som man vill installera). Vill gärna fånga upp eventuella felmeddelanden, där de markeras med hjälp av typ en linje över och under felmeddelandet, så de framträder mer.

Skrivet av pv2b:

Ditt script är inte effektivt med att ställa alla frågor först. Istället för att ställa en fråga om "vill du göra A", sedan gå och göra A, sedan gå tillbaka och fråga om du ska göra B, och sedan göra det. Mer effektivt vore att börja med att fråga vad användaren vill i början, och sedan göra allt i ett svep. Då kan användaren effektivt svara på alla frågorna och sedan koka en kopp kaffe, och komma tillbaks till en färdig installation.

Ditt script anropar t.ex. apt-get install så att det ställer frågor. Samma som ovan, när apt-get install kör så kommer den fråga om du vill installera paketen i fråga. Kanske inte önskvärt i ett automatiskt script. Kolla om apt-get har en flagga för att skippa denna frågan, och även andra interaktiva frågor.

Yepp! Detta finns redan i min att göra-lista, som även kan ses i README.md på GitHub När gränssnittet är klart (har ej påbörjat med det än), så försvinner problemet med din andra punkt där.

Skrivet av pv2b:

Om användaren skriver fel på ett svar kraschar scriptet. Om användaren skriver till t.ex. "Hej" som svar på en ja/nej fråga så bör scriptet fråga igen, inte bara avsluta scriptet.

Hm. Ja, det kan ju faktiskt vara något, att den inte avbryter allt, utan bara fortsätter. Men detta kommer ju inte vara något problem när gränssnittet väl är klart, där användaren väljer vad som ska installeras och sen installeras allt utan några bekräftelser eller nått sånt.

Skrivet av pv2b:

Scriptet i sig är inte scriptbart. Istället för en massa ja/nej-frågor interkativt, fundera på att lägga på lite flaggor till scriptet istället, eller iaf ha den möjligheten. Då kan du lätt skriva ett oneliner-script som installerar allt du vill ha precis som du vill ha det istället för att svara på en massa j/n-frågor.

Hur menar du där, gällande flaggorna? Känner mig som en amatör igen, trots över 10 års erfarenhet inom webb-programmering, haha!

Skrivet av pv2b:

Ditt script anropar apt-get alldeles för många gånger i onödan. Du kör en apt-get update många gånger i scriptet vilket bara tar en massa tid i onödan, sen kör du apt-get install flera gånger med olika listor på paket. Mycket smartare att bygga en lista på paket först och sedan installera allt på en gång. Men det värsta är ändå nästan längst ner i scriptet:

sudo apt-get --purge remove chromium sudo apt-get --purge remove chromium-browser sudo apt-get --purge remove chrome sudo apt-get --purge remove google-chrome sudo apt-get --purge remove firefox sudo apt-get --purge remove mozilla sudo apt-get --purge remove iceweasel sudo apt-get --purge remove seamonkey sudo apt-get --purge remove lynx sudo apt-get --purge remove www-browser sudo apt-get --purge remove links sudo apt-get --purge remove links2 sudo apt-get --purge remove w3m sudo apt-get --purge remove elinks sudo apt-get --purge remove epiphany sudo apt-get --purge remove konqueror

Det här bör bara vara en rad.

Tack för tipset

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
Hedersmedlem
Skrivet av Airikr:

Hur menar du där, gällande flaggorna? Känner mig som en amatör igen, trots över 10 års erfarenhet inom webb-programmering, haha!

Jag tänkte att istället för att scriptet frågar "Vill du installera XYZ" så anropar du scriptet med en parameter --install-xyz.

Om du ändå tänkte fixa något GUI runt det hela så blir det ju mycket enklare att anropa scriptet från GUI om du gör så.

Permalänk
Medlem
Skrivet av Crazy Ferret:

Så, gällande kodkvalitet: gör inte en sak flera gånger om du kan göra den en gång. Skapa funktioner. Din kod skulle utan tvekan kunna bantas ner till under hundra rader (spontan gissning, troligen än mindre).

"Brottades" med att lägga in funktioner, men jag gav upp till slut. Skapade istället en for-loop som går igenom varje steg, och filen bantades ner med över 300 rader

Skrivet av pv2b:

Jag tänkte att istället för att scriptet frågar "Vill du installera XYZ" så anropar du scriptet med en parameter --install-xyz.

Om du ändå tänkte fixa något GUI runt det hela så blir det ju mycket enklare att anropa scriptet från GUI om du gör så.

Aha. Du menar så Ja, det kan vara en lösning fram tills jag har fått gränssnittet att fungera, faktiskt. Tack för tipset

Uppdaterade för övrigt filen i går. Om du vill, så får du gärna gå igenom koden igen

Visa signatur

Citera mig om du vill att jag ska hitta till ditt svar.
airikr.me /device:desktop. Andra projekt: Keizai, Koroth & Serenum.

Permalänk
Medlem
Skrivet av Airikr:

"Brottades" med att lägga in funktioner, men jag gav upp till slut. Skapade istället en for-loop som går igenom varje steg, och filen bantades ner med över 300 rader

Bra jobbat.
Se nu följande exempel och klura över det:

#!/bin/bash print_line() { echo -e "-- -- -- -- -- -- -- -- -- -- -- -- -- --\n" } print_header() { echo ; print_line echo -ne "$1\n" print_line } print_header "Success.\nFoo"

$ ./cmdexample.sh -- -- -- -- -- -- -- -- -- -- -- -- -- -- Success. Foo -- -- -- -- -- -- -- -- -- -- -- -- -- --

Det finns två anledningar till att vi scriptar saker:
1) För att få konsekventa resultat. Optimalt sett vill vi även uppnå idempotens, d.v.s. att oavsett hur många gånger vi kör ett script är slutresultatet detsamma.
2) För att vi är lata. Det finns inget värre än att göra samma sak två gånger.

Fundera nu på vad mer det är du gör flera gånger med minimala skillnader och hur du kan bryta ner det i mindre moduler där du matar modulen med indata.

Nämen, oj, när du har gjort det för alla dina funktioner och dessutom kanske lagt till ett ramskript som skickar över scriptet via ssh till godtyckliga maskiner, ja då har du i praktiken börjat skriva dig ett orkestreringsverktyg inte alltför olikt ett avskalat Ansible.

Visa signatur

Desktop: AMD 3950X, 64 GB RAM, Nvidia 4070 ... (Windows 11)
Serverdesktop: AMD 5600G, 64 GB RAM (Proxmox)
Labbmiljö: Supermicro SC825 X9DRi-F 2xE5-2667v2 64GB RAM
Kamera: Canon R5, Canon RF 100-500, Laowa 100mm f/2.8, Canon RF 24-70 f/2,8