리눅스 명령행 인자: 명령어 옵션과 따옴표, 옵션 끝 표시, $1, $# 받기
Linux-opdrachtregelargumenten (command-line argument) zijn waarden die je aan een programma meegeeft door ze, gescheiden door spaties, achter de opdrachtnaam te schrijven. We gaven op een AlmaLinux 9-server opties, aanhalingstekens, jokertekens en -- mee aan een testscript dat de ontvangen argumenten ongewijzigd toont: het opsplitsen van de argumenten deed de shell, en het lezen van de opties deed elke opdracht zelf.
De uitvoer hieronder is precies wat we kregen met bash 5.1 onder het root-account van een AlmaLinux 9.8-server. De testscripts en voorbeeldbestanden zijn in een aparte werkmap gemaakt, en het pad /home/user/www is een voorbeeldwaarde.
1️⃣ Wat zijn Linux-opdrachtregelargumenten?
Typ je op de opdrachtregel iets als [opdracht arg1 arg2], dan splitst de shell de woorden op bij de spaties. Het eerste woord wordt het programma dat wordt uitgevoerd, en de overige woorden gaan op volgorde als argumenten naar dat programma.
Om de meegegeven argumenten te zien, maakten we args.sh in de werkmap. $0 bevat de naam waarmee het werd gestart, $# het aantal argumenten, en vanaf $1 staan de argumenten op volgorde. De vierkante haken laten zien waar elk argument begint en eindigt.
#!/bin/bash
echo "\$0 = $0"
echo "\$# = $#"
i=1
for a in "$@"; do
echo "\$$i = [$a]"
i=$((i+1))
doneWe gaven het script uitvoerrechten en startten het met drie woorden: a, b en c.
./args.sh a b c$0 = ./args.sh
$# = 3
$1 = [a]
$2 = [b]
$3 = [c]De drie woorden kwamen in $1, $2 en $3 terecht, en $# was 3. Start je het script door de naam achter bash te schrijven, dan bevat $0 precies de geschreven naam, args.sh.
bash args.sh a b c$0 = args.sh
$# = 3
$1 = [a]
$2 = [b]
$3 = [c]Alleen $0 veranderde in args.sh; de drie argumenten en het aantal bleven hetzelfde als eerst.
2️⃣ Opdrachtregelargumenten en opdrachtopties
Linux-opdrachten schrijf je meestal in de volgorde [opdracht -optie argument]. Opties veranderen hoe de opdracht werkt, en argumenten bepalen met welke bestanden, paden of waarden de opdracht werkt.
ls -l /home/user/wwwVoor de shell is ook -l gewoon een argument. Toen we dezelfde woorden aan args.sh meegaven, kwam -l in $1 en het pad in $2.
./args.sh -l /home/user/www$0 = ./args.sh
$# = 2
$1 = [-l]
$2 = [/home/user/www]-l lezen als optie is het werk van ls. Daarom betekent dezelfde letter per opdracht iets anders: -n bij head bepaalt het aantal regels dat wordt getoond, terwijl -n bij ls eigenaren als nummer toont in plaats van als naam.
Sommige opties nemen het woord direct erna als eigen waarde. In de opdracht find neemt -type de f en -name de "*.txt" als waarde; zo'n waarde die bij een optie hoort, heet een optieargument.
find . -type f -name "*.txt"De . vooraan in deze opdracht is een argument dat bij geen enkele optie hoort en bepaalt de map waar het zoeken begint.
3️⃣ Notaties van Linux-opdrachtopties
Korte opties beginnen met één streepje, bestaan uit één letter en kun je aan elkaar schrijven. Eerst toonden we de map site in de werkmap met [ls -l -a].
ls -l -a sitetotal 8
drwxr-xr-x 3 root root 52 Oct 28 16:00 .
drwxr-xr-x 3 root root 137 Oct 29 01:20 ..
-rw-r--r-- 1 root root 17 Oct 28 16:00 .htaccess
drwxr-xr-x 2 root root 23 Oct 28 16:00 css
-rw-r--r-- 1 root root 14 Oct 28 16:00 index.htmlDaarna vergeleken we dat met diff met de uitvoer van [ls -la], waarin de twee letters aan elkaar staan.
diff <(ls -l -a site) <(ls -la site) && echo samesameDe twee uitvoeren verschilden geen enkel teken. Lange opties beginnen met twee streepjes en schrijf je als woord; --all van ls is dezelfde optie als -a, dus [ls -l --all site] gaf ook hetzelfde resultaat.
Lange opties worden ook geaccepteerd als je alleen het begin schrijft, zolang dat maar bij één optie past. --al paste bij twee opties, --all en --almost-all, dus ls toonde geen lijst en stopte met afsluitcode 2.
ls --al sitels: option '--al' is ambiguous; possibilities: '--all' '--almost-all'
Try 'ls --help' for more information.Opties met een waarde kun je op verschillende manieren schrijven. Toon je met head de eerste twee regels van a.txt, dan kan de korte optie de waarde direct vastgeplakt krijgen: [-n2].
head -n2 a.txtalpha
betaBij de lange optie koppel je de waarde met een isgelijkteken: [--lines=2].
head --lines=2 a.txtalpha
betaAlle vier de vormen, ook [-n 2] en [--lines 2] met een spatie, toonden de twee regels alpha en beta.
ls, head en cat lezen hun opties met de functie getopt_long van de C-bibliotheek. Toen we de drie programmabestanden met strings bekeken, bevatten ze allemaal deze functienaam.
Om dezelfde regels vanuit de shell te controleren, gebruik je de opdracht getopt uit util-linux. Achter -o schrijf je de korte opties en achter -l de lange; een dubbele punt achter een letter betekent dat de optie een waarde verwacht.
getopt -o lan: -l all,lines: -- -la -n 2 --all a.txt -l -a -n '2' --all -- 'a.txt'De aan elkaar geschreven -la werd gesplitst in -l en -a, en -n 2 werd samengevoegd tot -n met de waarde 2. a.txt, dat geen optie is, werd naar het einde verplaatst, achter --.
4️⃣ Argumenten tussen aanhalingstekens en jokertekens
Een bestandsnaam met een spatie moet tussen aanhalingstekens staan om als één argument mee te gaan.
./args.sh "my file.txt" report.txt$0 = ./args.sh
$# = 2
$1 = [my file.txt]
$2 = [report.txt]Zonder aanhalingstekens werden my en file.txt apart opgesplitst en werd $# 3. Geef je het zo mee aan ls of cat, dan zoeken die naar twee bestanden met de namen my en file.txt.
./args.sh my file.txt report.txt$0 = ./args.sh
$# = 3
$1 = [my]
$2 = [file.txt]
$3 = [report.txt]Jokertekens vervangt de shell door bestandsnamen voordat het programma ze ontvangt. Toen we in de werkmap *.txt meegaven, kwamen de vier bestanden die op .txt eindigen binnen, op naam gesorteerd.
./args.sh *.txt$0 = ./args.sh
$# = 4
$1 = [a.txt]
$2 = [b.txt]
$3 = [my file.txt]
$4 = [report.txt]De "*.txt" tussen aanhalingstekens werd niet door de shell vervangen en werd letterlijk één argument. Bij opties zoals -name van find, waar het programma het patroon zelf vergelijkt, geef je het zo tussen aanhalingstekens mee.
./args.sh "*.txt"$0 = ./args.sh
$# = 1
$1 = [*.txt]Ook lege aanhalingstekens gaan mee als één leeg argument. Bij [./args.sh '' b] was $# 2 en was $1 leeg.
5️⃣ Einde van de opdrachtopties (--)
Een argument dat met een streepje begint, zoals een bestand met de naam -n, leest de opdracht als optie. Toen we [ls -n] uitvoerden in de map dash, die alleen dat ene bestand bevat, nam ls -n niet als bestandsnaam maar als optie voor numerieke uitvoer en toonde het de inhoud van de map.
ls -ntotal 4
-rw-r--r-- 1 0 0 10 Oct 28 16:00 -nArgumenten achter -- worden niet als opties gelezen, ook als ze met een streepje beginnen. [ls -- -n] toonde alleen de bestandsnaam -n.
ls -- -n-nBinnen één opdracht worden dezelfde tekens voor en na -- verschillend gelezen. Toen we -n twee keer aan cat meegaven, werd de eerste -n gelezen als optie voor regelnummers en de -n na -- als bestandsnaam, zodat de inhoud van het bestand met regelnummers verscheen.
cat -n -- -n 1 dash fileJe kunt er ook een pad voor zetten en ./-n schrijven; dan begint het argument niet met een streepje en wordt het als hetzelfde bestand -n gelezen.
Dat -- als einde van de opties wordt gelezen, is ook een regel aan de kant van de opdracht. Toen we het meegaven aan args.sh, dat geen opties leest, kwam ook -- ongewijzigd in $1 terecht.
./args.sh -- -a$0 = ./args.sh
$# = 2
$1 = [--]
$2 = [-a]De POSIX Utility Conventions bepalen dat de eerste -- die geen optieargument is, wordt aanvaard als het einde van de opties. Daarom schrijf je bij opdrachten die deze conventies volgen bestandsnamen die met - beginnen achter --.
6️⃣ Opdrachtregelargumenten ontvangen in een shellscript
Een shellscript leest de ontvangen argumenten via positionele parameters en speciale parameters. Ook main(int argc, char *argv[]) van een C-programma krijgt dezelfde argumenten; naast elkaar gezet ziet dat er zo uit.
| Parameter | Waarde die erin staat | C-functie main |
|---|---|---|
| $0 | Naam van het uitgevoerde script | argv[0] |
| $1 ~ $9 | Eerste tot en met negende argument | argv[1] ~ argv[9] |
| ${10} | Vanaf het tiende argument tussen accolades | argv[10] |
| $# | Aantal argumenten, $0 niet meegeteld | argc - 1 |
| "$@" | Alle argumenten, elk apart | argv[1] tot het einde |
| "$*" | Alle argumenten met spaties samengevoegd tot één | — |
Een Python-programma krijgt dezelfde argumenten als de lijst sys.argv. Toen we met [python3 -c] drie argumenten meegaven, kwam de tussen aanhalingstekens gezette my file.txt in één element van de lijst terecht, en in het eerste element stond -c.
python3 -c 'import sys; print(sys.argv)' a "my file.txt" -l['-c', 'a', 'my file.txt', '-l']"$@" en "$*" geven tussen dubbele aanhalingstekens een verschillend resultaat. Om het verschil te zien, maakten we star.sh, dat beide vormen na elkaar toont.
#!/bin/bash
echo 'with "$@"'
printf ' [%s]\n' "$@"
echo 'with "$*"'
printf ' [%s]\n' "$*"We startten star.sh met drie argumenten: a, "b c" en d.
./star.sh a "b c" dwith "$@"
[a]
[b c]
[d]
with "$*"
[a b c d]"$@" gaf de drie argumenten apart door, terwijl "$*" ze met spaties samenvoegde en als één doorgaf.
Geef je de ontvangen argumenten ongewijzigd door aan een andere opdracht, gebruik dan dus "$@".
shift gooit $1 weg en schuift de overige argumenten één plaats naar voren. Je gebruikt het in scripts die eerst één optie lezen en de rest als lijst met bestanden behandelen.
We maakten shift.sh, dat $1 en $# voor en na shift toont.
#!/bin/bash
echo "before shift: \$1 = $1, \$# = $#"
shift
echo "after shift: \$1 = $1, \$# = $#"We startten shift.sh met drie argumenten: -v, a.txt en b.txt.
./shift.sh -v a.txt b.txtbefore shift: $1 = -v, $# = 3
after shift: $1 = a.txt, $# = 2Vanaf het tiende argument zet je het getal tussen accolades, zoals ${10}. We maakten ten.sh, dat $10 en ${10} naast elkaar toont.
#!/bin/bash
echo "\$10 = $10"
echo "\${10} = ${10}"We gaven ten.sh 11 argumenten mee, a tot en met k.
./ten.sh a b c d e f g h i j k$10 = a0
${10} = j$10 werd a0, dus $1 met een 0 erachter, terwijl ${10} het tiende argument j werd.
🔲 Simulator voor opdrachtregelargumenten
In de simulator hieronder kun je aanhalingstekens, jokertekens en -- aan args.sh meegeven en ook zelf opdrachten typen om te zien hoe ls en getopt opties lezen en hoe star.sh en shift.sh argumenten ontvangen.
🔢 FAQ & aanbevolen content
Wildcards
[Speciale shelltekens] Linux-jokertekens (metatekens)
Een artikel dat met voorbeelden uitlegt hoe je bestandsnamen selecteert met jokertekens zoals * en ? en met tekenklassen.
Meerdere commando's
[Linux] 5 manieren om opdrachten te koppelen (puntkomma, pipe, ampersand..)
Een artikel over vijf manieren om meerdere opdrachten op één regel uit te voeren met een puntkomma, een pipe, &&, || en &.
Tekst tonen
echo-opdracht: From expansie en quoting
Een artikel over hoe je met echo tekst en variabelewaarden toont, en over de opties ervan.
ℹ️ Affiliatemelding
De content van deze site bevat affiliatelinks. Koopt een bezoeker via een van deze links een product of dienst, dan ontvangt deze site een commissie van de verkoper. Het bedrag dat de koper betaalt (bij acties gaat het omlaag ↓) wordt daardoor niet hoger. De vermelde prijzen, kortingen en voorraad gelden op het moment van schrijven en kunnen afwijken; controleer ze daarom vóór je aankoop bij de verkoper. Producten worden gekozen en beoordeeld volgens onze eigen criteria, en commissies hebben geen invloed op de volgorde of de inhoud van de beoordelingen.