Hlavní navigace

Programování pod Linuxem pro všechny (2)

Jakub Matys

Vítám vás u nového dílu našeho programovacího seriálu. Jak už jsem v minulém dílu předeslal, dnes se budeme zabývat funkcí getopt_long, naučíme se používat systémové proměnné a vytvářet dočasné soubory. Tak tedy s chutí do toho!

getopt_long()

Jak už jste si určitě někdy všimli, většině programů se při jejich spouštění předávají parametry. Někdy to je jen písmeno uvedené pomlčkou (-), ale někdy to jsou dvě pomlčky (–) následované slovem či více slovy. Tyto parametry mění chod programu. Pro obsluhu parametrů se používá funkce getopt_long. Při použití této funkce musíte do svého kódu vložit hlavičkový soubor getopt.h.

Při použití funkce getopt_long musíte definovat dvě speciální datové struktury. První je znakový řetězec obsahující krátké volby. Píší se bez pomlčky a ty, za nimiž bude náslodovat další argument, jsou následovány dvojtečkou. Pokud chcete používat dlouhé volby, musíte sestavit pole, které bude obsahovat struktury struct option. Každá tato struktura představuje jednu volbu a obsahuje čtyři položky. První položkou je jméno volby (znakový řetězec uzavřený do uvozovek); druhá obsahuje 1, pokud má za volbou následovat další argument, nebo 0. Třetí položkou je konstantaNULL a čtvrtou je odpovídající krátká volba. Posledními elementy by měly být nuly. Menší příklad pro názornost:

/* retezec obsahujici kratke volby */
const char *kratke_volby = "ho:i:";

/* pole s dlouhymi volbami */
const struct option long_options[] = {
   { "help",     0, NULL, 'h' },
   { "output",   1, NULL, 'o' },
   { "input"     1, NULL, 'i' },
   { NULL,       0, NULL, 0   }
};

Při volání funkce getopt_long je nutné předat jako parametry proměnné argc, argv, řetězec s krátkými volbami a pole s dlouhými volbami. Funkce pracuje následovně:

  • Po každém volání provádí syntaktickou analýzu volby a vrátí jednoznakové písmeno pro volbu, nebo –1, pokud další volby nebyly nalezeny.
  • Běžně se funkce volá v cyklu, a tak se postupně zpracují všechny volby předané z shellu. Každá konkrétní volba se pak zpracuje v příkazu switch.
  • Pokud funkce getopt_long zjistí zadání neplatné volby, zobrazí chybové hlášení a vrátí znak ?. Většina programů na to reaguje ukončením a vypsáním zprávy o zadání neplatné volby.
  • Pokud za volbami následuje další argument, vrátí se globální proměnná optarg ukazující na textový řetězec.
  • Po ukončení syntaktické analýzy vrátí funkce getopt_long v globální proměnné optind index (do pole argv) prvního argumentu, který není volbou.

Všechny výše napsané informace si předvedeme na příkladu:

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

/* Jmeno programu. */
const char *program_name;

/* Tato funkce vypise napovedu do vystupniho
 * proudu STREAM(stderr, stdout) a ukonci se
 * s kodem EXIT_CODE.
 */
void print_help(FILE *stream, int exit_code)
{
  fprintf(stream, "Usage: %s options\n", program_name);
  fprintf(stream, "  -h  --help         Display this help screen.\n"
                  "  -o  --output file  Write output to file.\n"
                  "  -i  --input file   Read input from file.\n");
  exit(exit_code);
}

/* Funkci main zacina program. */
int main(int argc, char *argv[])
{
  int next_option;

  /* Retezec obsahujici kratke volby */
  const char *short_options = "ho:i:";

  /* Pole struktur s dlouhymi volbami */
  const struct option long_options[] = {
    { "help",    0, NULL, 'h' },
    { "output",  1, NULL, 'o' },
    { "input",   1, NULL, 'i' },
    { NULL,      0, NULL,  0  }
  };

  /* Jmeno souboru pro vystup nebo NULL pro stdout */
  const char *output_file = NULL;

  /* Jmeno souboru pro vstup nebo NULL pro stdin */
  const char *input_file = NULL;

  /* Jmeno programu je ulozeno v promene argv[0]. */
  program_name = argv[0];

  do {
    next_option = getopt_long(argc, argv, short_options, long_options, NULL);

    switch(next_option)
    {
      case 'h': /* -h nebo --help */
           print_help(stdout, 0);
      case 'o': /* -o nebo --output */
           output_file = optarg;
           break;
      case 'i': /* -i nebo --input */
           input_file = optarg;
           break;
      case '?': /* Uzivatel specifikoval neznamou volbu */
           print_help(stderr, 1);
      case -1 : /* Konec */
           break;
      default:
           abort();
    }
  } while(next_option != -1);

  /* Volby byly zpracovany. Promena OPTIND ukazuje
   * na prvni argument, ktery neni volbou.
   */

  ...
  ...
  ...

  return(0); /* Ukonceni programu s kodem 0 */
} 

To by bylo vše k funkci getopt_long. Někomu by se mohlo zdát ze je její použití příliž pracné. Ale pokud byste si vytvořili vlastní funkci, stálo by vás to mnohem více úsilí.

Systémové proměnné

Každý program běžící v Linuxu ma přiřazeno jisté prostředí (enviroment). Prostředí je množina dvojic [systémová proměnná, hodnota]. Systémové proměnné jsou znakové řetězce a jejich jména se píší velkými písmeny. Je vysoce pravděpodobné, že jste se už setkali s proměnnými USER, HOME, PATH, DISPLAY. Proměnné můžete vytvářet v shellu zápisem PROMENNA=hodnota, poté je nutné je exportovat z shellu do prostředí příkazem export PROMENNA. Zjistit hodnotu proměnné můžete příkazem echo $PROMENNA. A konečně, chcete-li vypsat prostředí shellu, zadejte příkaz printenv.

V programu lze systémové proměnné zpřístupňovat pomocí funkce getenv, která je popsána v stdlib.h. Tato funkce má jediný argument, a to jméno proměnné, jejíž hodnotu chcete zjistit. Pokud není systémová proměnná definována, vrací funkce NULL, jinak vrací textový řetězec, který obsahuje hodnotu proměnné. Jestliže budete chtít nastavit nebo zrušit systémovou proměnnou, použijte funkci setenvresp. unsetenv. Menší příklad použití systémových proměnných:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   char *conf_file = getenv("CONFIG_FILE");
   if(conf_file == NULL)
      /* Promenna CONFIG_FILE nebyla definovana,
       * pouzije se defaultni configuracni soubor
       */
      conf_file = "/etc/config";
   ...
   ...
   ...

   return(0);
}

To by bylo pro dnešek vše, slíbené vytváření dočasných souborů si necháme na příště. A navíc si povíme něco o statických a dynamických knihovnách.

Našli jste v článku chybu?

6. 2. 2004 19:36

Mikuláš Patočka (neregistrovaný)

char také na některých architekturách je od 0 do 255 a nenabývá záporných hodnot. Zda je char znaménkový nebo neznaménkový není v normě definováno.

4. 2. 2004 23:28

Jan (neregistrovaný)

getopt_long je zrovna ten typ funkce, o ktere by mel zacatecnik slyset co nejpozdeji. Funkcim s vedlejsimi efekty (pouziva statickou enumeracni promenou) se kazdy moderni programator obloukem vyhne. Takhle se programovalo v minulem stoleti !

Navic takova strojovna pro tak jednoduchou akci jako je parsing parametru ? Citim za tim ducha tech, co zplodili X server. A to je moc smutna kapitola. Uvidime jestli se k tomu autor v nekterem dilu dostane.



DigiZone.cz: SES zajistí HD pro M7 Group

SES zajistí HD pro M7 Group

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

120na80.cz: Rovnátka, která nejsou vidět

Rovnátka, která nejsou vidět

Vitalia.cz: 7 originálních adventních kalendářů pro mlsné

7 originálních adventních kalendářů pro mlsné

Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Měšec.cz: Za palivo zaplatíte mobilem (TEST)

Za palivo zaplatíte mobilem (TEST)

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Lupa.cz: Obchod budoucnosti je bez front, košíků i pokladen

Obchod budoucnosti je bez front, košíků i pokladen

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

Měšec.cz: Exekuční poradna: ptejte se online

Exekuční poradna: ptejte se online

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách