Mestring av Linux-kommandolinjen og Bash-skripting · leksjon

Orkestrering av arbeidsmengder med GNU parallel

Fordel store datamengder på flere kjerner med GNU parallel, jobbplasser og sortering av resultater.

Leksjon 3 av 413 trinn

Orkestrering av arbeidsmengder med GNU parallel er en gratis leksjon i Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Mestring av Linux-kommandolinjen og Bash-skripting, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hva er GNU parallel, og hvorfor bruke det?

GNU parallel er et skallverktøy som lar Dem kjøre jobber parallelt på én eller flere maskiner. I stedet for å behandle en stor liste med elementer ett etter ett i en for-løkke, fordeler parallel arbeidet på alle tilgjengelige CPU-kjerner samtidig.

  • Hastighet: En oppgave som tar 8 minutter sekvensielt, kan fullføres på omtrent 1 minutt på en maskin med 8 kjerner.
  • Enkelhet: Det godtar inndata fra stdin, filer eller argumentlister — ingen manuell prosesshåndtering.
  • Sikkerhet: Utdata fra ulike jobber holdes adskilt; resultater flettes aldri sammen.

Installer det med sudo apt install parallel (Debian/Ubuntu) eller brew install parallel (macOS). Bekreft installasjonen med parallel --version.

Deres første parallel-kommando

Den enkleste formen for parallel leser elementer fra stdin og kjører en kommando for hvert element. Plassholderen {} representerer det gjeldende inndataelementet.

Eksempelet nedenfor komprimerer fem loggfiler samtidig ved hjelp av gzip. Uten parallel ville hver fil blitt komprimert etter tur. Med verktøyet komprimeres opptil N filer (der N = antallet CPU-kjerner) samtidig.

#!/usr/bin/env bash
# Create sample files first
for i in 1 2 3 4 5; do
  dd if=/dev/urandom bs=1M count=2 of="log_${i}.txt" 2>/dev/null
done

# Compress all of them in parallel
ls log_*.txt | parallel gzip {}

echo "Done. Compressed files:"
ls log_*.txt.gz

Kontrollere jobbplasser med -j

Som standard kjører parallel én jobb per CPU-kjerne. De kan overstyre dette med flagget -j (eller --jobs).

  • -j 4 — kjør nøyaktig 4 jobber samtidig
  • -j 0 — kjør like mange jobber som det finnes inndataelementer (brukes med forsiktighet!)
  • -j 200% — kjør dobbelt så mange jobber som det finnes CPU-kjerner (nyttig for I/O-bundet arbeid)
  • -j 50% — bruk bare halvparten av de tilgjengelige kjernene

For CPU-bundne oppgaver er -j $(nproc) ofte optimalt. For nettverks- eller disk-I/O-oppgaver kan De trygt overskride antallet kjerner, fordi jobbene bruker mesteparten av tiden på å vente.

#!/usr/bin/env bash
# Show how many cores are available
echo "CPU cores: $(nproc)"

# Run 8 sleep jobs but limit to 3 at a time
# -j 3 means at most 3 jobs run simultaneously
seq 1 8 | parallel -j 3 'echo "Starting job {}"; sleep 1; echo "Done job {}"'

echo "All jobs finished."

Lese inndata fra filer og argumenter

parallel er fleksibelt når det gjelder hvor inndatalisten leses fra. De er ikke begrenset til å sende inndata gjennom stdin.

  • Fra en fil: parallel -a urls.txt wget {}
  • Argumentliste direkte på kommandolinjen: parallel echo ::: apple banana cherry
  • Flere argumentkilder (kartesisk produkt): parallel echo {1}-{2} ::: a b c ::: 1 2 — produserer a-1, a-2, b-1, b-2, c-1, c-2
  • Eksplisitt fra stdin: cat list.txt | parallel -j4 process {}

Skilletegnet ::: forteller parallel at de følgende verdiene skal brukes som en argumentkilde i stedet for at inndata skal leses fra stdin.

#!/usr/bin/env bash
# Inline list with :::
parallel echo 'Hello from {}' ::: Alice Bob Carol Dave

echo '---'

# Cartesian product: combine two lists
# Generates: dev-v1, dev-v2, prod-v1, prod-v2
parallel echo 'Deploy {1} to env {2}' ::: v1 v2 ::: dev prod

Plassholdere: manipulere inndatatoken

parallel tilbyr flere plassholdersubstitusjoner som lar Dem hente ut deler av inndatastrengen automatisk — svært nyttig når inndataene er filstier.

  • {} — hele inndataelementet
  • {.} — inndata uten filendelsen (report.csv → report)
  • {/} — bare basename (fjerner katalogbanen)
  • {//} — bare katalogbanen
  • {/.} — basename uten filendelse

Dette eliminerer behovet for kall til basename / dirname inne i jobbkommandoen, slik at pipeliner blir ryddigere og raskere.

#!/usr/bin/env bash
# Demonstrate placeholder substitutions
parallel --dry-run 'convert {} -resize 800x600 {.}_thumb.jpg' \
  ::: /photos/vacation/beach.png /photos/work/team.png

# {.}  strips extension: /photos/vacation/beach
# Result command shown (--dry-run does NOT execute):
#  convert /photos/vacation/beach.png -resize 800x600 /photos/vacation/beach_thumb.jpg
#  convert /photos/work/team.png      -resize 800x600 /photos/work/team_thumb.jpg
echo 'No files were changed (dry run)'

Holde utdata i rekkefølge med --keep-order

Når jobber blir ferdige på ulike tidspunkter, vises stdout-utdataene i den rekkefølgen jobbene fullføres. Dette kan gjøre logger vanskelige å lese og analyse i etterfølgende trinn upålitelig.

To flagg styrer rekkefølgen på utdataene:

  • --keep-order (-k) — skriver ut utdataene fra hver jobb i samme rekkefølge som inndataene, selv om en senere jobb blir ferdig først. Utdataene bufres til tidligere jobber er ferdige.
  • --line-buffer — en mellomløsning: skriver ut komplette linjer etter hvert som de kommer, uten å vente på at jobben skal bli ferdig, men fletter aldri sammen halvskrevne linjer.

Bruk -k når mottakeren i neste trinn forventer resultater i inndat rekkefølge (for eksempel ved bygging av en sortert rapport). Utelat det når rekkefølgen ikke har betydning og De vil se resultatene så snart som mulig.

#!/usr/bin/env bash
# Without -k: output order is unpredictable
echo '--- Without --keep-order ---'
seq 5 1 1 | parallel 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'

echo

# With -k: output always appears as 5, 4, 3, 2, 1
echo '--- With --keep-order (-k) ---'
seq 5 1 1 | parallel -k 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'

Gruppere utdata for å unngå sammenblanding

Selv med ordnede utdata kan linjene blandes med linjer fra en annen jobb som kjører samtidig, hvis en jobb skriver ut flere linjer. parallel løser dette automatisk ved å bufre hele stdout og stderr for hver jobb og deretter skrive dem ut som én atomisk blokk når jobben er ferdig.

Denne oppførselen er aktivert som standard. Deaktiver den med --ungroup hvis De trenger direkte strømming av utdata (for eksempel for langvarige jobber med fremdriftsindikatorer), men da kan utdata blandes igjen.

  • Standard: utdata grupperes per jobb — trygt for parsing.
  • --ungroup: utdata strømmes direkte — egnet for interaktiv overvåking.
  • --line-buffer: kompromiss — linjer deles aldri opp, men jobber kan blandes ved linjegrensene.

Sende argumenter i shell-funksjoner

Noen ganger består arbeidet De vil parallellisere av mer enn én enkelt kommando — det er en shell-funksjon med flere trinn. De kan sende en funksjon til parallel ved å bruke export -f sammen med env_parallel, eller ved å kalle bash -c direkte.

Den sikreste portable metoden for komplekse jobber er mønsteret bash -c '...'. Plassholderen {} sendes som $1 når De avslutter med _ {}.

#!/usr/bin/env bash
# Define a multi-step processing function
process_item() {
  local item="$1"
  echo "[START] $item"
  # Simulate two steps
  sleep 0.2
  local result=$(echo "$item" | tr '[:lower:]' '[:upper:]')
  echo "[END]   $item -> $result"
}

export -f process_item

# Run the function in parallel for each input
echo 'alpha beta gamma delta epsilon' | tr ' ' '\n' \
  | parallel -j 3 process_item {}

Begrense hastighet og prøve på nytt med --delay og --retries

Når De kaller eksterne tjenester (API-er, eksterne servere eller databaser) parallelt, trenger De ofte hastighetsbegrensning og feiltoleranse.

  • --delay N — vent N sekunder mellom oppstarten av hver nye jobb (desimalverdier som 0.5 er tillatt). Hindrer at en tjeneste overbelastes.
  • --retries N — hvis en jobb avsluttes med en status som ikke er null, prøves den på nytt opptil N ganger før den avsluttes. Hvert nytt forsøk teller som en ny jobbplass.
  • --timeout N — avslutt en jobb hvis den kjører lenger enn N sekunder. Sammen med --retries håndterer dette jobber som henger, på en kontrollert måte.

Eksempel: last ned 50 URL-er med høyst 4 samtidige forbindelser, 0,5 sekunders forsinkelse mellom oppstarter og 3 nye forsøk ved feil.

#!/usr/bin/env bash
# Simulate downloading URLs with throttling and retries
# (using echo instead of curl so this is self-contained)

download_url() {
  local url="$1"
  # Randomly fail ~30% of the time to demo --retries
  if (( RANDOM % 10 < 3 )); then
    echo "FAIL: $url" >&2
    return 1
  fi
  echo "OK:   $url downloaded"
}

export -f download_url

printf 'https://example.com/file%d\n' $(seq 1 10) \
  | parallel -j 4 --delay 0.2 --retries 3 download_url {}

echo 'All downloads attempted.'

Fordele arbeid på eksterne verter med --sshloginfile

parallel kan fordele jobber transparent til eksterne maskiner via SSH, slik at verktøyet fungerer som en lettvektsløsning for klyngeberegning uten spesiell klyngeprogramvare.

  • --sshlogin user@host — kjør jobber på en bestemt ekstern vert.
  • --sshloginfile machines.txt — les en liste over verter fra en fil (én per linje). Bruk : som en spesialoppføring for også å bruke den lokale maskinen.
  • --transfer — kopier inndatafilen til den eksterne verten før behandlingen.
  • --return {} — kopier resultatfilen tilbake når jobben er ferdig.
  • --cleanup — slett overførte filer fra den eksterne verten etter tilbakehentingen.

Den eksterne verten må ha parallel installert, og SSH-autentisering med nøkler må være konfigurert (uten passordforespørsler).

Fremdriftsrapportering og logging

For langvarige arbeidsmengder er det viktig å overvåke fremdriften og diagnostisere feil i etterkant.

  • --progress — skriver ut en løpende sammendragslinje som viser hvor mange jobber som kjører, er fullført og gjenstår.
  • --eta — beregner forventet tid til ferdigstillelse basert på gjennomsnittlig varighet for jobbene så langt.
  • --joblog results.log — skriver en tabulatorseparert loggfil med én rad per fullført jobb, inkludert avslutningskode, kjøretid og kommandoen som ble kjørt. Svært nyttig ved revisjon av feil.
  • --resume --joblog results.log — hopper over jobber som allerede finnes (med avslutningskode 0) i loggfilen. Hvis en batchkjøring blir avbrutt, kan De fortsette uten å utføre vellykkede jobber på nytt.

Kombinasjonen --joblog + --resume er en av de kraftigste funksjonene i GNU parallel for robuste produksjonspipelines.

#!/usr/bin/env bash
LOGFILE="/tmp/parallel_demo_$$.log"

# Run jobs and record results to a log
seq 1 12 | parallel \
  --jobs 4 \
  --progress \
  --joblog "$LOGFILE" \
  'sleep 0.1; echo "Processed item {}"'

echo
echo '=== Job Log (first 5 entries) ==='
head -6 "$LOGFILE"

# Show only failed jobs (exit value != 0)
echo '=== Failed jobs ==='
awk 'NR>1 && $7 != 0 { print $0 }' "$LOGFILE" || echo '(none)'

rm -f "$LOGFILE"

Kunnskapssjekk: flagg for jobbplasser

Test forståelsen Deres av hvordan parallel styrer samtidighet.

Oppsummering av leksjonen: orkestrering av arbeidsmengder med GNU parallel

De har gått gjennom de viktigste verktøyene for å fordele store inndatamengder på CPU-kjerner med GNU parallel. Dette er det viktigste å ta med seg:

  • Grunnleggende bruk: send en liste gjennom parallel command {} — {} erstattes av hvert inndataelement.
  • Jobbplasser (-j): styrer samtidighet presist — bruk antallet kjerner for CPU-bundet arbeid og høyere prosenter for I/O-bundet arbeid.
  • Plassholdere ({.}, {/}, {//}, {/.}) henter enkelt ut deler av stier uten ekstra kommandoer.
  • Kontroll av utdata: -k bevarer inndaterekkefølgen; standard gruppering hindrer at linjer blandes; --ungroup gir direkte strømming.
  • Robusthet: --retries, --timeout og --delay gjør parallelle pipelines robuste mot ustabile jobber og hastighetsbegrensninger.
  • Sporbarhet: --joblog registrerer resultatet for hver jobb; --resume lar Dem fortsette der De slapp etter et avbrudd.
  • Utskalering: --sshloginfile fordeler jobber til eksterne maskiner via SSH uten ekstra klyngeinfrastruktur.

Når De behersker disse alternativene, blir parallel en produksjonsklar orkestrator for arbeidsmengder, direkte integrert i skallet.

Gratis å komme i gang

Lær deg Bash med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
88

Ofte stilte spørsmål

Er leksjonen «Orkestrering av arbeidsmengder med GNU parallel» gratis?

Ja – hele teksten i «Orkestrering av arbeidsmengder med GNU parallel» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Mestring av Linux-kommandolinjen og Bash-skripting-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hva lærer jeg i «Orkestrering av arbeidsmengder med GNU parallel»?

Fordel store datamengder på flere kjerner med GNU parallel, jobbplasser og sortering av resultater. Du øver på Mestring av Linux-kommandolinjen og Bash-skripting med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Mestring av Linux-kommandolinjen og Bash-skripting?

Ingen tidligere erfaring er nødvendig. Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Orkestrering av arbeidsmengder med GNU parallel»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Mestring av Linux-kommandolinjen og Bash-skripting-leksjonen?

Ja. Alle Mestring av Linux-kommandolinjen og Bash-skripting-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Profilering av skript og unngåelse av unødvendige subshell-er
  2. Parallellitet med xargs -P og bakgrunnsjobber
  3. Orkestrering av arbeidsmengder med GNU parallel
  4. Strømmende pipelines og navngitte pipes for høy gjennomstrømning
← Tilbake til Mestring av Linux-kommandolinjen og Bash-skripting