GNU/Linux >> Tutoriales Linux >  >> Linux

Ejemplos de C argc y argv para analizar argumentos de línea de comandos

Cada vez que ejecuta un programa en una terminal, puede pasar algunos argumentos que espera el programa, que se pueden usar durante la ejecución del programa. Aquí, el sistema proporciona una instalación interna para mantener todos los argumentos pasados ​​por el usuario mientras ejecuta el programa. Estos argumentos se conocen como "argumentos de la línea de comandos".

En este tutorial, mapearemos la comprensión de los argumentos de la línea de comandos con el programa de trabajo para comprenderlo mejor de una manera nítida y clara. Pero antes de saltar al programa, debemos saber cómo el sistema proporciona la facilidad de los argumentos de la línea de comandos. Como sabemos, cada programa en C debe tener la función main() y la facilidad de los argumentos de la línea de comandos la proporciona la propia función main(). Cuando se proporciona a continuación, la declaración se usa en el programa, y ​​luego el programa tiene la facilidad de usar/manipular los argumentos de la línea de comandos.

int main (int argc, char *argv[])

Aquí, el parámetro argc es el recuento del total de argumentos de la línea de comandos pasados ​​al ejecutable en la ejecución (incluido el nombre del ejecutable como primer argumento). El parámetro argv es la matriz de cadena de caracteres de cada argumento de la línea de comando que se pasa al ejecutable en la ejecución. Si es nuevo en la programación C, primero debe comprender cómo funciona la matriz C.

A continuación se muestra el programa de trabajo que utiliza el argumento de la línea de comandos.

 #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;
 }

A continuación se muestra la salida cuando se ejecuta el programa.

$ ./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

En el resultado anterior, podemos ver que el recuento total de argumentos se mantiene internamente mediante el parámetro "argc" de main() que contiene el valor '7' (en el que un argumento es el nombre del ejecutable y '6' son argumentos que se pasan al programa). Y, todos Los valores de los argumentos se almacenan en el parámetro "argv" de main(), que es una matriz de cadenas de caracteres. Aquí, la función principal () almacena cada valor de argumento como una cadena de caracteres. Podemos ver, iterando sobre la matriz "argv", podemos obtener todos los argumentos pasados ​​en el programa.

Hay una declaración más de la función principal () que proporciona una facilidad adicional para trabajar en variables de entorno dentro del programa. Al igual que los argumentos mantenidos en la matriz argv[], la función main() tiene una función interna para mantener todas las variables de entorno del sistema en una matriz de cadenas de caracteres que se pueden tomar como un parámetro de la función main(). A continuación se muestra la declaración.

int main (int argc, char *argv[], char **envp)

A continuación se muestra el programa de trabajo que usa el argumento de la línea de comando junto con las variables de entorno.

#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;
}

El resultado del programa anterior se muestra a continuación.

$ ./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
$

En la salida anterior, podemos ver que todas las variables de entorno del sistema se pueden obtener como tercer parámetro de la función main() que se recorren en el programa y se muestran en la salida.

Pasar argumentos de la línea de comandos para programar y manipular argumentos

A continuación se muestra un programa que funciona con argumentos de línea de comandos.

#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;
}

El resultado del programa anterior se muestra a continuación.

 $ ./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

En el resultado anterior, podemos ver que los argumentos de la línea de comandos se pueden manipular en el programa; todos los argumentos se obtienen como cadenas de caracteres que se pueden convertir en números enteros, flotantes, largos como se muestra en el programa. Incluso cualquier cadena de caracteres si se pasa como una ruta de cualquier archivo que pueda ser utilizada por el programa para la operación de manejo de archivos de ese archivo. Podemos ver en el programa anterior, (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c) la ruta del archivo se pasa como un argumento de línea de comando que se usa dentro del programa para abrir el archivo y cerrarlo.

API Getopt()

Si exploramos más los argumentos de la línea de comandos, tenemos una API muy potente:getopt(). Facilita al programador analizar las opciones de la línea de comandos. El programador puede proporcionar una lista de opciones de línea de comandos obligatorias u opcionales para getopt(). Puede determinar si la opción de línea de comando es válida o no válida según las opciones de línea de comando esperadas por el programa. Hay pocas variables internas específicas de getopt() como “optarg, optopt, opterr”

  • Optarg :contiene un puntero al argumento de la opción válida de la línea de comando
  • Optar :contiene la opción de línea de comando si falta la opción de línea de comando obligatoria
  • Opciones :establecido en distinto de cero cuando se proporciona una opción no válida o no se proporciona el valor de la opción de línea de comando obligatoria

A continuación se muestra un programa básico para comprender el análisis de las opciones de la línea de comandos.

#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;
 }

La salida del programa anterior se muestra a continuación con algunas combinaciones de opciones de línea de comandos:

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

En el programa anterior, 'i' y 'o' se toman como opciones de línea de comando de entrada y salida obligatorias para el programa que usa la API getopt().

Ahora tendríamos una explicación básica de cada caso ejecutado en el programa anterior:

  • En el Caso 1, se proporcionan ambas opciones de línea de comando obligatorias con sus argumentos, que se manejan correctamente en los primeros dos casos de condición de cambio del programa.
  • En el Caso 2, no se proporciona el valor de la opción de entrada obligatoria, pero podemos ver que getopt() no es lo suficientemente inteligente y se considera "-o" como valor de la opción de línea de comando 'I'. No es un caso de error para getopt(), pero el propio programador puede agregar inteligencia para manejar tal caso.
  • En el caso 3, solo se especifica la opción de línea de comando sin su valor y esta es una opción obligatoria, por lo que en este caso getopt() devolvería '?' y la variable "optopt" se establece en 'i' para confirmar que el valor de la opción de entrada obligatoria es desaparecido.
  • En el caso 4, falta el valor de la opción de salida obligatoria.
  • En el caso 5, se proporciona una opción de línea de comando no válida que no es una opción de línea de comando obligatoria u opcional. En este caso, getopt() devolvió '?' y optopt no está configurado porque es un carácter desconocido que getopt() no espera.

Linux
  1. El comando Sed de Linux:uso y ejemplos

  2. Tutorial de comandos agradable y renice de Linux (7 ejemplos)

  3. Cómo contar el número de líneas en un archivo en Linux (ejemplos de comandos wc y nl)

  4. Ejemplos de comandos mkdir y rmdir en Linux

  5. Ejemplos de comandos swapon y swapoff en Linux

Comando Diff en Linux con ejemplos

Opciones de comando y ejemplos de Tee Command en Linux

50 ejemplos simples y útiles del comando Buscar en Linux

16 Ejemplos Prácticos y Útiles del Comando Echo en Linux

19 consejos y trucos útiles para la línea de comandos de Linux

Argumentos Pycharm y sys.argv