Želite li da pokrenete Python skripte koristeći argumente komandne linije? U ovom vodiču naučićete kako da parsirate argumente komandne linije uz pomoć modula `sys`, `getopt` i `argparse` u Python-u.
U Python-u, kada želite da pročitate unos od korisnika, koristićete funkciju `input()`. Međutim, za neke aplikacije, možda će biti neophodno da prosledite određene argumente prilikom pokretanja skripte putem komandne linije.
Ovaj vodič će vam pokazati kako da pokrenete Python skriptu sa opcijama i argumentima iz komandne linije. Zatim ćemo koristiti Python-ove ugrađene module za parsiranje tih opcija i argumenata.
Započnimo!
Razumevanje `sys.argv` u Python-u
Ako ste programirali u C-u, znate da je jedan od osnovnih načina za prosleđivanje argumenata programu putem komandne linije. Da biste to postigli, možete da struktuirate `main` funkciju na sledeći način:
#include<stdio.h> int main(int argc, char **argv){ //argc: broj argumenata //argv: vektor argumenata //obradite argumente return 0; }
Ovde, `argc` predstavlja broj argumenata, dok `argv` predstavlja vektor argumenata.
Pokretanje Python skripti sa argumentima komandne linije
U Python-u, skriptu možete pokrenuti preko komandne linije koristeći `python3 filename.py`. Prilikom toga, možete uneti i proizvoljan broj argumenata:
$ python3 filename.py arg1 arg2 ... argn
Modul `sys` pruža jednostavan pristup i obradu ovih argumenata komandne linije. `sys.argv` je lista svih argumenata koje prosleđujemo prilikom pokretanja Python skripte.
Evo primera gde pokrećemo `main.py` sa argumentima komandne linije:
$ python3 main.py hello world python script
Kroz vektor argumenata možemo proći koristeći jednostavnu `for` petlju i funkciju `enumerate`:
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# Izlaz arg0:main.py arg1:hello arg2:world arg3:python arg4:script
Vidimo da je prvi argument (na indeksu 0) ime Python datoteke, dok naredni argumenti počinju od indeksa 1.
Ovo je osnovni funkcionalni program koji prihvata i obrađuje argumente komandne linije. Međutim, postoje određeni problemi:
- Kako korisnici programa znaju koje argumente treba da unesu?
- I šta ovi argumenti predstavljaju?
Ovo nije sasvim jasno. Da biste ovo rešili, možete koristiti module `getopt` ili `argparse`. To ćemo istražiti u narednim odeljcima.✅
Parsiranje argumenata komandne linije pomoću Python-ovog `getopt`-a
Naučimo sada kako da parsiramo argumente komandne linije koristeći ugrađeni modul `getopt`.
Nakon uvoza funkcije `getopt` iz modula `getopt`, definišemo argumente za parsiranje, kratke opcije i duge opcije za pokretanje skripte. Treba nam parsiranje argumenata, počevši od indeksa 1 u `sys.argv`, stoga se parsira `sys.argv[1:]`.
U našem primeru, biće nam potrebni argumenti za poruku i naziv datoteke. Koristićemo `m` i `f` kao kratke opcije, a `message` i `file` kao duge opcije.
Kako da označimo da određena opcija zahteva argument?
- U kratkim opcijama, argument opcije označavamo dodavanjem dvotačke (:) iza kratkog naziva opcije.
- Slično, kod dugih opcija, argument označavamo dodavanjem znaka = iza duge opcije. Na ovaj način možemo da uhvatimo opcije i njihove argumente.
Kada dodamo te oznake, naš kod u `main.py` će izgledati ovako:
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args)
Ovde promenljiva `opts` sadrži opcije i argumente kao listu torki. Svi pozicioni argumenti koje prosledimo biće sačuvani u promenljivoj `args`.
Možemo uneti poruku i naziv datoteke prilikom pokretanja skripte, koristeći kratke ili duge opcije.
Pokrećemo `main.py` pomoću dugih opcija:
$ python3 main.py --message hello --file somefile.txt
Opcije i argumenti su sada torke u promenljivoj `opts`. Pošto nismo prosledili pozicione argumente, `args` je prazna lista.
# Izlaz [('--message', 'hello'), ('--file', 'somefile.txt')] []
Isto možemo postići koristeći i kratke opcije:
$ python3 main.py -m hello -f somefile.txt
# Izlaz [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠ Kratku opciju `-m` u ovom primeru ne treba mešati sa zastavicom komandne linije `-m`, koja se koristi za pokretanje modula kao glavnog modula prilikom pokretanja Python skripte.
Na primer, koristili biste `python3 -m unittest main.py` za pokretanje `unittest` kao glavnog modula prilikom pokretanja `main.py`.
Rekli smo da će svi ostali pozicioni argumenti koje prosledimo biti sačuvani u promenljivoj `args`. Evo primera:
$ python3 main.py -m hello -f somefile.txt another_argument
Lista `args` sada sadrži pozicioni argument `another_argument`.
# Izlaz [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
Ovde je `opts` lista torki, kroz koju možemo da prođemo, raspakujemo torke i izvučemo argumente koji odgovaraju određenim opcijama.
Šta da radimo sa imenom datoteke i porukom nakon obrade argumenata? Otvorićemo datoteku u režimu pisanja i upisati poruku, pretvorenu u velika slova, u datoteku.
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args) for option, argument in opts: if option == "-m": message = argument if option == '-f': file = argument with open(file,'w') as f: f.write(message.upper())
Pokrenimo `main.py` sa kratkim opcijama i argumentima komandne linije:
$ python main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
Nakon pokretanja `main.py`, u radnom direktorijumu možemo videti `thisfile.txt`. Sadrži string `hello` pretvoren u velika slova (`HELLO`).
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
Kako parsirati argumente komandne linije pomoću `argparse`-a
Modul `argparse`, koji je takođe deo Python standardne biblioteke, pruža funkcionalnost za parsiranje argumenata komandne linije i kreiranje interfejsa komandne linije.
Da bismo parsirali argumente komandne linije, importujemo klasu `ArgumentParser` iz modula `argparse`. Ovde instanciramo `arg_parser`, objekat `ArgumentParser`:
from argparse import ArgumentParser arg_parser = ArgumentParser()
Zatim ćemo dodati dva argumenta komandne linije:
- `message`: string poruke i
- `file`: naziv datoteke sa kojom želimo da radimo.
Pozivamo metod `add_argument()` na `arg_parser` da bismo dodali oba ova argumenta. U pozivu metode `add_argument()`, možemo postaviti pomoć za string (opis argumenta).
arg_parser.add_argument('message',help='string poruke') arg_parser.add_argument('file',help='ime datoteke')
Do sada smo instancirali `arg_parser` i dodali argumente komandne linije. Kada se program pokrene iz komandne linije, metod `parse_args()` na `arg_parser` će vratiti vrednosti argumenata.
Ovde hvata prostor imena argumenata u promenljivoj `args`. Stoga, možemo koristiti `args.argument_name` da dobijemo vrednosti argumenata.
Nakon što dobijemo vrednosti argumenata, u datoteku upisujemo string poruke sa zamenjenim malim i velikim slovima (koristeći string metod `swapcase()`).
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Sve zajedno, naša `main.py` datoteka izgleda ovako:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message',help='string poruke') arg_parser.add_argument('file',help='ime datoteke') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Razumevanje upotrebe argumenata komandne linije
Da biste videli uputstvo o argumentima prilikom pokretanja `main.py`, koristite opciju `–help`, kao što je prikazano:
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message string poruke file ime datoteke optional arguments: -h, --help prikazuje ovu pomoćnu poruku i izlazi
Ne postoje opcioni argumenti, a `message` i `file` su oba obavezni pozicioni argumenti. Alternativno, možete koristiti i kratku opciju `-h`:
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message string poruke file ime datoteke optional arguments: -h, --help prikazuje ovu pomoćnu poruku i izlazi
Kao što se vidi, oba argumenta su podrazumevano pozicioni. Dakle, ako ne prosledite jedan ili više ovih argumenata, doći će do greške.
Ovde smo prosledili pozicioni argument `Hello` za string poruke, ali nismo dali nikakvu vrednost za argument datoteke.
I dobićemo grešku koja nam govori da je argument datoteke obavezan.
$ python3 main.py Hello usage: main.py [-h] message file main.py: error: sledeći argumenti su neophodni: file
Kada pokrenemo `main.py` sa oba poziciona argumenta, vidimo da prostor imena `args` sadrži vrednosti argumenata.
$ python3 main.py Hello file1.txt
# Izlaz Namespace(file="file1.txt", message="Hello")
Sada, ako ispitamo sadržaj trenutnog radnog direktorijuma, vidimo da je skripta kreirala datoteku `file1.txt`:
$ ls file1.txt main.py
Originalni string poruke je `Hello`, a nakon zamene slova, string u datoteci `file1.txt` je `hELLO`.
$ cat file1.txt hELLO
Kako da argumente komandne linije učinimo opcionim
Da biste argumente komandne linije učinili opcionim, dodajte prefiks `–` imenu argumenta.
Izmenimo `main.py` da bismo argumente poruke i datoteke učinili opcionim.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='string poruke') arg_parser.add_argument('--file',help='ime datoteke')
Pošto su argumenti komandne linije sada opcioni, možemo postaviti podrazumevane vrednosti za njih.
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
U ovom trenutku, datoteka `main.py` sadrži sledeći kod:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='string poruke') arg_parser.add_argument('--file',help='ime datoteke') args = arg_parser.parse_args() print(args) if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt" with open(file,'w') as f: f.write(message.swapcase())
Ako proverimo uputstvo, videćemo da su i `message` i `file` sada opcioni argumenti. To znači da sada možemo pokrenuti `main.py` bez oba ova argumenta.
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help prikazuje ovu pomoćnu poruku i izlazi --message MESSAGE string poruke --file FILE ime datoteke
$ python3 main.py
U prostoru imena argumenata, i datoteka i poruka su `None`.
# Izlaz Namespace(file=None, message=None)
Vidimo da se koriste podrazumevano ime datoteke i poruka, `myfile.txt` i `Python3`. Datoteka `myfile.txt` sada postoji u radnom direktorijumu:
$ ls file1.txt main.py myfile.txt
I sadrži string `Python3` sa zamenjenim malim i velikim slovima:
$ cat myfile.txt pYTHON3
Takođe, možemo koristiti argumente `–message` i `–file` da bi komanda bila čitljivija.
$ python3 main.py --message Coding --file file2.txt
# Izlaz Namespace(file="file2.txt", message="Coding")
Vidimo `file2.txt` u radnom direktorijumu:
$ ls file1.txt file2.txt main.py myfile.txt
I sadrži string `coding`, kao što se i očekivalo.
$ cat file2.txt cODING
Zaključak
Evo rezimea onoga što smo naučili u ovom vodiču:
- Slično programskom jeziku C, u Python-u možete pristupiti argumentima komandne linije prolazeći kroz vektor argumenata `sys.argv`. `sys.argv[0]` je naziv Python skripte. Stoga nas zanima parsiranje argumenata `sys.argv[1:]`.
- Međutim, radi bolje čitljivosti i dodavanja opcija, možete koristiti module `getopt` i `argparse`.
- Modul `getopt` možete koristiti za parsiranje liste argumenata komandne linije počevši od indeksa 1 do kraja liste. Možete definisati i kratke i duge opcije.
- Kada opcija prihvata argument, možete da odredite dvotačku (:) i znak `=` posle kratke i duge opcije, respektivno.
- Pomoću Python-ovog modula `argparse` možete instancirati objekat `ArgumentParser` i koristiti metod `add_argument()` da dodate željeni pozicioni argument. Koristite `–` ispred imena argumenta da biste ga učinili opcionim.
- Da biste preuzeli vrednosti argumenata komandne linije, pozovite metod `parse_args()` na objektu `ArgumentParser`.
Zatim naučite kako da izvršite bezbedno heširanje u Python-u.