Перейти к основному содержимому

Аргументы командной строки

Простая передача аргументов

Одним из способов передачи данных в программу - передача их через аргументы командной строки при ее вызове.

ls -lt /etc
cat /etc/hosts

В Си программе, при запуске управление передается в функцию main. Эта функция получает на вход аргументы командной строки, которые можно в дальнейшем обработать.

  • Первый аргумент функции main - argc, содержит количество аргументов переданных в программу.

  • Второй аргумент - argv массив ссылок на отдельные слова переданных аргументов.

Внимание!

Нулевой аргумент - это всегда название исполняемого файла самой программы

Пример:

  1. Создать файл main.c и добавить в него код:

    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    for(int i = 0; i < argc; i++){
    printf("argc = %d, argv = %s", i, argv[i])
    }

    return 0;
    }
  2. Скомпилировать программу

    gcc main.c -o programm
  3. Запустить программу с аргументами

    programm Hello World

Ввыод на консоли:

Вывод на консоль

Функция getopt()

В системе Linux существует два вида параметров: короткие и длинные. Короткие параметры начинаются с одного дефиса и имеют длину в один символ, длинные параметры начинаются с двух дефисов и могут иметь длинное имя, которое целесообразно использовать в скриптах (чтобы потом можно было вспомнить, что и как происходит). Кроме этого любой параметр может иметь или не иметь значение.

Примеры параметров:

-h       // короткий параметр
--help // длинный параметр

-s 10 // параметры со значениями
--size 10
--size=10

Cуществует несколько специальных функций предназначенных для разбора списка переданных параметров:

int getopt(...) - Обрабатывает короткие параметры

int getopt_long(...) - Обрабатывает короткие и длинные параметры

int getopt_long_only(...) - Обрабатывает параметры только как длинные

Определение функции getopt(...) выглядит следующим образом:

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;

Эта функция последовательно перебирает переданные параметры. Для работы в функцию передается количество параметров argc, массив параметров argv[] и специальная строка optstring, в которой перечисляются названия коротких параметров и признаки того, что параметры должны иметь значение. Например, если программа должна воспринимать три параметра a, b, F , то такая строка бы выглядела как "abF". Если параметр должен иметь значение, то после буквы параметра ставится двоеточие, например параметр F и d имеют значения, а параметры e, a и b не имеют, тогда эта строка могла бы выглядеть как "eF:ad:b". Если параметр может иметь (т.е. может и не иметь) значение, то тогда ставится два знака двоеточия, например "a::" (это специальное расширение GNU). Если optstring содержит "W:", то тогда параметр -W opt переданный в программу, будет восприниматься как длинный параметр --opt. Это связано с тем, что параметр W зарезервирован в POSIX.2 для расширения возможностей.

Для перебора параметров функцию getopt() надо вызывать в цикле. В качестве результата возвращется буква названия параметра, если же параметры кончились, то функция возвращает -1. Индекс текущего параметра хранится в optind, а значение параметра помещается в optarg (указатель просто указывает на элемент массива argv[]). Если функция находит параметр не перечисленный в списке, то выводится сообщение об ошибке в stderr и код ошибки сохраняется в opterr, при этом в качестве значения возврящается "?". Вывод ошибки можно запретить, если установить opterr в 0.

main.c
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
int rez = 0;

// opterr = 0;
while ( (rez = getopt(argc, argv, "ab:C::d")) != -1){
switch (rez) {
case 'a': printf("found argument \"a\".\n"); break;
case 'b': printf("found argument \"b = %s\".\n", optarg); break;
case 'C': printf("found argument \"C = %s\".\n", optarg); break;
case 'd': printf("found argument \"d\"\n"); break;
case '?': printf("Error found !\n"); break;
} // switch
} // while
} // main

Cкомпилировать данную программку и запустить:

gcc main.c -o test
./test ./test -a -b -d -C

Вывод на консоль:

found argument "a".
found argument "b = -d".
found argument "C = (null)".
./test -b1 -b2 -b 15

Вывод на консоль:

found argument "b = 1".
found argument "b = 2".
found argument "b = 15".

Для демонстрации того, как функция getopt вылавливает ошибки следует задать параметр, которого нет в списке:

./test -h -a

Выод на консоль:

./test: invalid option -- h
Error found !
found argument "a".

Функция вывела сообщение об ошибке в stderr. Для отключения вывода сообщений надо в программе перед вызовом функции вставить opterr=0;.

Скомпилировать и запустить программу:

./test -h -a

Вывод на консоль:

Error found !
found argument "a".

Теперь сообщение не выдается, зато как и раньше можно обработать саму ошибку.