Setiap kali Anda menjalankan program di terminal, Anda dapat melewatkan beberapa argumen yang diharapkan oleh program, yang dapat digunakan selama eksekusi program. Di sini, sistem menyediakan fasilitas internal untuk mempertahankan semua argumen yang diteruskan dari pengguna saat menjalankan program. Argumen-argumen ini dikenal sebagai “Argumen baris perintah”.
Dalam tutorial ini, kita akan memetakan pemahaman argumen baris perintah dengan program kerja untuk memahaminya dengan lebih jelas dan jelas. Namun sebelum melompat ke program, kita harus mengetahui bagaimana sistem menyediakan fasilitas argumen baris perintah. Seperti yang kita ketahui, setiap program C harus memiliki fungsi main() dan fasilitas argumen baris perintah disediakan oleh fungsi main() itu sendiri. Ketika diberikan deklarasi di bawah ini digunakan dalam program, dan kemudian program memiliki fasilitas untuk menggunakan/memanipulasi argumen baris perintah.
int main (int argc, char *argv[])
Di sini, parameter argc adalah jumlah total argumen baris perintah yang diteruskan ke executable saat eksekusi (termasuk nama executable sebagai argumen pertama). parameter argv adalah larik string karakter dari setiap argumen baris perintah yang diteruskan ke executable saat dieksekusi. Jika Anda baru mengenal pemrograman C, Anda harus terlebih dahulu memahami cara kerja array C.
Diberikan di bawah ini adalah program kerja menggunakan argumen baris perintah.
#include <stdio.h> int main (int argc, char *argv[]) { int i=0; printf("\ncmdline args count=%s", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } printf("\n"); return 0; }
Diberikan di bawah ini adalah output ketika program dijalankan.
$ ./cmdline_basic test1 test2 test3 test4 1234 56789 cmdline args count=7 exe name=./cmdline_basic arg1=test1 arg2=test2 arg3=test3 arg4=test4 arg5=1234 arg6=56789
Pada output di atas, kita dapat melihat jumlah argumen total dikelola secara internal oleh parameter “argc” dari main() yang memegang nilai '7' (di mana satu argumen adalah nama yang dapat dieksekusi dan '6' adalah argumen yang diteruskan ke program). Dan, semua nilai argumen disimpan dalam parameter “argv” dari main() yang merupakan array dari string karakter. Di sini, fungsi main() menyimpan setiap nilai argumen sebagai string karakter. Kita dapat melihat, dengan mengulangi array “argv”, kita bisa mendapatkan semua argumen yang dilewatkan dalam program.
Ada satu lagi deklarasi fungsi main() yang memberikan fasilitas tambahan untuk bekerja pada variabel lingkungan di dalam program. Seperti, argumen yang dipertahankan dalam array argv[], fungsi main() memiliki fasilitas internal untuk memelihara semua variabel lingkungan sistem ke dalam array string karakter yang dapat diambil sebagai parameter fungsi main(). Diberikan di bawah ini adalah pernyataannya.
int main (int argc, char *argv[], char **envp)
Diberikan di bawah ini adalah program kerja menggunakan argumen baris perintah bersama dengan variabel lingkungan.
#include <stdio.h> int main (int argc, char *argv[], char **env_var_ptr) { int i=0; printf("\ncmdline args count=%d", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } i=0; while (*env_var_ptr != NULL) { i++; printf ("\nenv var%d=>%s",i, *(env_var_ptr++)); } printf("\n"); return 0; }
Output dari program di atas diberikan di bawah ini.
$ ./env test1 test2 cmdline args count=3 exe name=./env arg1=test1 arg2=test2 env var1=>SSH_AGENT_PID=1575 env var2=>KDE_MULTIHEAD=false env var3=>SHELL=/bin/bash env var4=>TERM=xterm env var5=>XDG_SESSION_COOKIE=5edf27907e97deafc70d310550995c84-1352614770.691861-1384749481 env var6=>GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/sitaram/.gtkrc-2.0:/home/sitaram/.kde/share/config/gtkrc-2.0 env var7=>KONSOLE_DBUS_SERVICE=:1.76 env var8=>KONSOLE_PROFILE_NAME=Shell env var9=>GS_LIB=/home/sitaram/.fonts env var10=>GTK_RC_FILES=/etc/gtk/gtkrc:/home/sitaram/.gtkrc:/home/sitaram/.kde/share/config/gtkrc env var11=>WINDOWID=29360154 env var12=>GNOME_KEYRING_CONTROL=/run/user/sitaram/keyring-2Qx7DW env var13=>SHELL_SESSION_ID=f7ac2d9459c74000b6fd9b2df1d48da4 env var14=>GTK_MODULES=overlay-scrollbar env var15=>KDE_FULL_SESSION=true env var16=>http_proxy=http://10.0.0.17:8080/ env var17=>USER=sitaram env var18=>LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: env var19=>XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0 env var20=>XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0 env var21=>SSH_AUTH_SOCK=/tmp/ssh-kIFY5HttOJxe/agent.1489 env var22=>ftp_proxy=ftp://10.0.0.17:8080/ env var23=>SESSION_MANAGER=local/Sitaram:@/tmp/.ICE-unix/1716,unix/Sitaram:/tmp/.ICE-unix/1716 env var24=>DEFAULTS_PATH=/usr/share/gconf/kde-plasma.default.path env var25=>XDG_CONFIG_DIRS=/etc/xdg/xdg-kde-plasma:/etc/xdg env var26=>DESKTOP_SESSION=kde-plasma env var27=>PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games env var28=>PWD=/home/sitaram/test_progs/cmdline env var29=>socks_proxy=socks://10.0.0.17:8080/ env var30=>KONSOLE_DBUS_WINDOW=/Windows/1 env var31=>KDE_SESSION_UID=1000 env var32=>LANG=en_IN env var33=>GNOME_KEYRING_PID=1478 env var34=>MANDATORY_PATH=/usr/share/gconf/kde-plasma.mandatory.path env var35=>UBUNTU_MENUPROXY=libappmenu.so env var36=>KONSOLE_DBUS_SESSION=/Sessions/1 env var37=>https_proxy=https://10.0.0.17:8080/ env var38=>GDMSESSION=kde-plasma env var39=>SHLVL=1 env var40=>HOME=/home/sitaram env var41=>COLORFGBG=15;0 env var42=>KDE_SESSION_VERSION=4 env var43=>LANGUAGE=en_IN:en env var44=>XCURSOR_THEME=Oxygen_White env var45=>LOGNAME=sitaram env var46=>XDG_DATA_DIRS=/usr/share/kde-plasma:/usr/local/share/:/usr/share/ env var47=>DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-mnJhMvd4jG,guid=435ddd41500fd6c5550ed8d2509f4374 env var48=>LESSOPEN=| /usr/bin/lesspipe %s env var49=>PROFILEHOME= env var50=>XDG_RUNTIME_DIR=/run/user/sitaram env var51=>DISPLAY=:0 env var52=>QT_PLUGIN_PATH=/home/sitaram/.kde/lib/kde4/plugins/:/usr/lib/kde4/plugins/ env var53=>LESSCLOSE=/usr/bin/lesspipe %s %s env var54=>XAUTHORITY=/tmp/kde-sitaram/xauth-1000-_0 env var55=>_=./env env var56=>OLDPWD=/home/sitaram/test_progs $
Pada output di atas, kita dapat melihat semua variabel lingkungan sistem dapat diperoleh parameter ketiga dari fungsi main() yang dilalui dalam program dan ditampilkan dalam output.
Melewati argumen baris perintah untuk memprogram dan memanipulasi argumen
Diberikan di bawah ini adalah program yang bekerja pada argumen baris perintah.
#include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i=0; int d; float f; long int l; FILE *file = NULL; printf("\ncmdline args count=%d", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } /* Conversion string into int */ d = atoi(argv[1]); printf("\nargv[1] in intger=%d",d); /* Conversion string into float */ f = atof(argv[1]); printf("\nargv[1] in float=%f",f); /* Conversion string into long int */ l = strtol(argv[2], NULL, 0); printf("\nargv[2] in long int=%ld",l); /*Open file whose path is passed as an argument */ file = fopen( argv[3], "r" ); /* fopen returns NULL pointer on failure */ if ( file == NULL) { printf("\nCould not open file"); } else { printf("\nFile (%s) opened", argv[3]); /* Closing file */ fclose(file); } printf("\n"); return 0; }
Output dari program di atas diberikan di bawah ini.
$ ./cmdline_strfunc 1234test 12345678 /home/sitaram/test_progs/cmdline/cmdline_strfunc.c cmdline args count=4 exe name=./cmdline_strfunc arg1=1234test arg2=12345678 arg3=/home/sitaram/test_progs/cmdline/cmdline_strfunc.c argv[1] in intger=1234 argv[1] in float=1234.000000 argv[2] in long int=12345678 File (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c) opened
Pada output di atas, kita dapat melihat bahwa argumen baris perintah dapat dimanipulasi dalam program; semua argumen diperoleh sebagai string karakter yang dapat diubah menjadi integer, float, sepanjang seperti yang ditunjukkan dalam program. Bahkan string karakter apa pun jika dilewatkan sebagai jalur file apa pun yang dapat digunakan oleh program untuk operasi penanganan file oh file itu. Kita dapat melihat pada program di atas, (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c ) path file dilewatkan sebagai argumen baris perintah yang digunakan di dalam program untuk membuka dan menutup file.
Getopt() API
Jika kita mengeksplorasi lebih banyak tentang argumen baris perintah, kita memiliki API yang sangat kuat – getopt(). Ini memfasilitasi programmer untuk mengurai opsi baris perintah. Programmer dapat memberikan daftar opsi baris perintah wajib atau opsional ke getopt(). Itu dapat menentukan apakah opsi baris perintah valid atau tidak valid sesuai program opsi baris perintah yang diharapkan. Ada beberapa getopt() variabel internal khusus seperti “optarg, optopt, opterr”
- Optarg :berisi pointer ke baris perintah argumen opsi yang valid
- Memilih :berisi opsi baris perintah jika opsi baris perintah wajib tidak ada
- Pengoptimal :disetel ke bukan nol ketika opsi yang tidak valid diberikan atau nilai opsi baris perintah wajib tidak diberikan
Diberikan di bawah ini adalah program dasar untuk memahami penguraian opsi baris perintah.
#include <stdio.h> #include <unistd.h> int main (int argc, char *argv[]) { int opt = 0; char *in_fname = NULL; char *out_fname = NULL; while ((opt = getopt(argc, argv, "i:o:")) != -1) { switch(opt) { case 'i': in_fname = optarg; printf("\nInput option value=%s", in_fname); break; case 'o': out_fname = optarg; printf("\nOutput option value=%s", out_fname); break; case '?': /* Case when user enters the command as * $ ./cmd_exe -i */ if (optopt == 'i') { printf("\nMissing mandatory input option"); /* Case when user enters the command as * # ./cmd_exe -o */ } else if (optopt == 'o') { printf("\nMissing mandatory output option"); } else { printf("\nInvalid option received"); } break; } } printf("\n"); return 0; }
Output dari program di atas diberikan di bawah ini dengan beberapa kombinasi opsi baris perintah:
Case1: $ ./cmdline_getopt -i /tmp/input -o /tmp/output Input option value=/tmp/input Output option value=/tmp/output Case2: $ ./cmdline_getopt -i -o /tmp/output Input option value=-o Case3: $ ./cmdline_getopt -i ./cmdline_getopt: option requires an argument -- 'i' Missing mandatory input option Case4: $ ./cmdline_getopt -i /tmp/input -o ./cmdline_getopt: option requires an argument -- 'o' Input option value=/tmp/input Missing mandatory output option Case5: $ ./cmdline_getopt -k /tmp/input ./cmdline_getopt: invalid option -- 'k' Invalid option received
Dalam program di atas, 'i' dan 'o' diambil sebagai opsi baris perintah input dan output wajib untuk program yang menggunakan getopt() API.
Kami sekarang akan memiliki penjelasan dasar dari setiap kasus yang dijalankan dalam program di atas:
- Dalam Kasus1, kedua opsi baris perintah wajib dengan argumennya disediakan yang ditangani dengan benar dalam dua kasus pertama dari kondisi sakelar program.
- Dalam Kasus2, nilai opsi input wajib tidak diberikan tetapi kita dapat melihat getopt() tidak cukup cerdas dan dianggap “-o” sebagai nilai opsi baris perintah 'I'. Ini bukan kasus kesalahan untuk getopt(), tetapi programmer sendiri dapat menambahkan kecerdasan untuk menangani kasus tersebut.
- Dalam Kasus3, hanya opsi baris perintah yang ditentukan tanpa nilainya dan ini adalah opsi wajib sehingga dalam kasus ini getopt() akan mengembalikan '?' dan variabel “optopt” disetel ke 'i' untuk mengonfirmasi nilai opsi input wajib adalah hilang.
- Dalam Kasus4, nilai opsi keluaran wajib tidak ada.
- Dalam Kasus5, opsi baris perintah yang tidak valid diberikan yang bukan merupakan opsi baris perintah wajib atau opsional. Dalam hal ini, getopt() mengembalikan '?' dan optopt tidak disetel karena karakter yang tidak dikenal tidak diharapkan oleh getopt().