Командная строка переключается не по порядку - PullRequest
1 голос
/ 20 октября 2010

Я работаю над программой на C ++, которая принимает имя файла в качестве входных данных командной строки, читает кучу данных из этого файла, вычисляет две вещи относительно данных и затем завершает работу. Одно из этих вычислений должно быть выполнено , но другое гораздо более необязательно, поэтому я подумал, что было бы неплохо добавить флаг -c, чтобы отключить его. Наивно, я просто всегда предполагал бы, что если пользователь дает два аргумента, первый должен переключать вычисления, а второй дает имя файла, но это становится намного более громоздким с большим количеством флагов. Какова стандартная практика, когда rm -rf "file", rm -fr "file" и rm "file" -rf работают как допустимые команды?

Ответы [ 6 ]

3 голосов
/ 20 октября 2010

Какова стандартная практика для того, чтобы команды rm -rf "file", rm -fr "file" и rm "file" -rf работали как допустимые команды?

Aмногие люди не согласны с этим, поэтому, похоже, нет стандартной практики, если только вы не нацелены на определенную аудиторию (то есть, когда пишете инструмент командной строки для linux, посмотрите, что делают «стандартные» утилиты).

В любом случае большинство библиотек в конечном итоге предоставляют вам следующие параметры:

  1. Переключатели : эти изолированные флаги в том, что после переключателя не ожидается никаких аргументов.Инструменты Unix, такие как tar и rm, часто позволяют вам указывать несколько флагов вместе, как в -rf флажках вашего примера.
  2. Опции : они указаны как переключатели, но ожидаюткакое-то значение после переключения.Например, gcc ожидает имя выходного файла после -o.Поскольку они ожидают параметры, они, очевидно, могут не указываться одновременно.
  3. Короткие длинные имена VS : у переключателей и параметров обычно есть два имени: однозначное, однозначное или двойное описательное имя (сравните -o и --output-file), хотя некоторые параметры, такие как справка или контроль многословия, часто имеют только длинное имя.
  4. Несколько конечных аргументов : если инструмент позволяет обрабатывать одновременнофайлы сразу, все они указаны в end только последовательности.Разрешение их чередования с другими параметрами и флагами приведет к кошмару.Опция -- для обозначения «конца опций» также удобна в том случае, если некоторые из этих конечных аргументов могут содержать тире.

Множество инструментов позволяют чередовать переключатели и опции, но множественные трейлингаргументы всегда в конце.

Конечно, вы найдете часто используемые инструменты, которые не соответствуют этим соглашениям, такие как cl.exe и link.exe от Microsoft.Более современные инструменты, похоже, сходятся к этому, в том числе candle.exe и light.exe от Microsoft для WIX.

Если вы хотите убедиться, что соблюдаете эти рекомендации (и сэкономите много времени), используйте "стандартную библиотеку, такую ​​как UNIX getopt() или опции программы boost.

Edit : существующие библиотеки часто генерируют опцию --help для вас, используя краткие описания, которые вы даете, когда задаетепереключатели и опции, которые вы ожидаете.

2 голосов
/ 20 октября 2010

Использовать Опции программы повышения . Пример:

po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("compression", po::value<int>(), "set compression level")
;

po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);    

if (vm.count("help")) {
    cout << desc << "\n";
    return 1;
}

if (vm.count("compression")) {
    cout << "Compression level was set to " 
 << vm["compression"].as<int>() << ".\n";
} else {
    cout << "Compression level was not set.\n";
}
1 голос
/ 20 октября 2010

Стандартная функция синтаксического анализа аргументов, используемая утилитами UNIX, например rm, - getopt(). Более новые команды могут использовать getopt_long(), который обрабатывает так называемые «длинные аргументы» из более чем одного символа (длинные --symbols против коротких -s).

Для примера его использования, посмотрите на эту реализацию rm, или просто посмотрите страницу руководства.

getopt() был портирован на Win32 / MFC. Один из таких портов XGetOpt .

0 голосов
/ 20 октября 2010

Требуемое поведение демонстрируется современными инструментами GNU, которые вы найдете в текущем дистрибутиве Linux.

Старое неприятное поведение можно увидеть в инструментах BSD, которые по умолчанию предоставляются во FreeBSD и OpenBSD.

Желаемое поведение:

  • способен объединить все короткие ключи без аргументов в одном месте
  • также может предоставлять короткие варианты отдельно.
  • может смешивать параметры и аргументы по желанию, предоставляя параметры до и после аргументов имени файла.
  • каждая опция также должна иметь длинную, подробную опцию, указанную двумя черточками.
  • две черточки сами по себе должны прекратить обработку опций: это позволяет обрабатывать имена файлов, которые выглядят как опции.

С GNU-версиями ls вы можете сделать это:
ls -al *.c -h *.h --reverse -t -- -filename-1 -filename-2

Это очень хорошо для пользователей командной строки. Так должно быть. Мы написали это.

BSD-версия ls будет подавлена ​​этим. Очень неприятно, что меня заставляют вернуться к началу команды, чтобы просто изменить некоторые параметры отображения.

0 голосов
/ 20 октября 2010

Или, если у вас есть повышение, program_options добивается цели ... http://www.boost.org/doc/libs/1_44_0/doc/html/program_options.html

0 голосов
/ 20 октября 2010

Поиск Google обнаруживает этот класс C ++, называемый «Anyoption». Похоже, это именно то, что вам нужно. http://www.hackorama.com/anyoption/

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

...