Отделение параметров от неопционных аргументов в программе командной строки - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь написать ограниченную версию ls с некоторыми опциями.

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

Например:

$ ls -l -t somefile anotherFile

$ ls somefile -lt anotherFile

имеют такое же поведение.

Для меня это две проблемы:

  1. Это затрудняет использование argc. Например, я бы рассматривал аргументы ls -lt и ls, чтобы оба имели 0 аргументов (кроме имени команды), однако argc считает -l аргументом.

Поэтому наивная реализация:

if( argc == 1) {list all the contents of cwd}

не работает.

Есть ли встроенный способ получения параметров, а также счетчика параметров или мне нужно свернуть свою собственную функцию?

  1. Я должен рассмотреть все возможные способы организации опций и быть осторожным, чтобы не перепутать опцию как имя файла или имя каталога. Кажется, самое чистое решение - отделить параметры от аргументов файла с самого начала. Есть ли идиоматический способ сделать это / есть стандартные вызовы библиотеки, которые делают это?

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Если у вас есть реализация Gnu getopt, она сделает все это за вас.

Стандарт Posix getopt прекращает обработку опций, когда достигает первого аргумента, не являющегося опцией,Это соответствует правилам Posix для разбора служебных аргументов, и многие из нас предпочитают такое поведение.Но другим нравится возможность смешивать опции и не опции, и это является нормой для утилит Gnu, если вы не установите переменную среды с неловким именем POSIXLY_CORRECT.

В соответствии с этим предпочтением Gnu getopt анализируетАргументы:

По умолчанию переставляется содержимое argv при сканировании, чтобы в конце концов все неопции были в конце.Это позволяет задавать параметры в любом порядке, даже если программы не были написаны, чтобы ожидать этого.

Обратите внимание на формулировку о перестановке аргументов.Это означает, что если вы начнете с

ls somefile -lt anotherFile

Gnu getopt будет:

  1. Сообщить о l
  2. Сообщить о t
  3. Сообщите об окончании опций (-1), оставив optind со значением 2 и argv, теперь выглядит так:

    ls -lt somefile anotherFile
    

Так что теперь вы можетеобработайте ваши неопционные аргументы с помощью:

for (int argno = optind; argno < argc; ++argno) {
  /* Do something with argv[argno] */
}

Кроме того, вы можете указать, сколько неопционных аргументов вы получили с помощью argc-optind, и если argc == optind, вы знаете, что их не было.

Разделение -lt на два варианта является стандартным Posix getopt behaviour.Вы можете комбинировать параметры lime, если первый не принимает аргумент.

0 голосов
/ 15 мая 2018

Встроенной справки для разбора аргументов нет, но getopt - это "стандартный" метод для разбора аргументов.

Для простых приложений я иногда добавляю что-то вроде:

int pos=0;
argc--;argv++;
while (argc > 0) {
  if (*argv[0]=='-') {
     switch ((*argv)[1]) {
       case 'l': //-l argument
         save_option_l(++argv);
         argc--; //we consumed one name
         break;
       //... other -options here ...
       default:
         usage("unrecognized option %s", *argv);   
     }
   }
   else {
     save_positional_argument(argv,pos++);
   }
   argv++;
   argc--;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...