Добавьте флаг к существующей терминальной команде

От этого вопроса: ls будет всегда перечислять файлы, которые удалит комната? @fkraiem прокомментирован и сказан:

Я несколько удивлен, что комната не имеет - флаг пробного прогона...

Это напомнило мне о сценарии, что я имел когда-то назад с помощью seq команда для генерации последовательности чисел от 1 - 100. Проблема состояла в том, что список имел префикс Item

seq 100

Сгенерированный:

1
2
3
...
100

Принимая во внимание, что я хотел:

Item 1
Item 2
Item 3
...
Item 100

Используя команду seq как пример, там так или иначе, я могу добавить a --prefix=[PREFIX] флаг, который автоматически добавляет префикс к сгенерированному списку последовательности?

Я не говорю о псевдонимах удара

2
задан 6 September 2018 в 02:56

2 ответа

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

  • проанализируйте параметры командной строки
  • прервите свою дополнительную опцию (и любой определенный для опции аргумент)
  • выполните новое действие
  • иначе передайте остающиеся аргументы исходной команде

Однако Ваш seq должен уже иметь опцию указать числовой формат, который может быть (ab), используемый для получения вида списка, который Вы хотите

   -f, --format=FORMAT
          use printf style floating-point FORMAT

Напр.

$ seq -f 'Item %.0f' 1 10
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10

В более общем плане Вы могли использовать printf например. printf 'Item %d\n' $(seq 1 100) или (использование встроенного расширения фигурной скобки удара) printf 'Item %d\n' {1..100}


BTW rm действительно имеет своего рода флаг пробного прогона, -i

-i     prompt before every removal

или (менее портативно)

-I     prompt once before removing  more  than  three  files,  or  when
      removing recursively; less intrusive than -i, while still giving
      protection against most mistakes
7
ответ дан 2 December 2019 в 01:27

Добавление флагов и существующих команд

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

  1. Изменение команды могло бы быть против условий лицензирования. Очень часто читатели ответов на этом сайте предполагают, что все - открытый исходный код и Весы в соответствии с Ubuntu, но собственное программное обеспечение также используется. Конечно, можно изменить любое программное обеспечение - это не вопрос компетентности кодирования или способности. Очень часто вопрос состоит в том, можно ли изменить его.
  2. Мобильность, в том смысле, что этот флаг работает над этой машиной, где Вы изменили его, но не другой. Мимоходом, документация. Предположите запись сценария, который использует измененную версию seq, но независимо от того, что флаг, который Вы добавили, не находится в странице справочника. Ваш коллега или другой человек, который будет читать этот сценарий, будут очень смущены относительно того, почему тот флаг не находится в руководстве, и возможно еще более запутанный относительно того, почему флаг не работает; еще больше забавы состоит в том, когда у Вас есть полный набор утилит, которые могут зависеть от той конкретной команды с тем конкретным флагом. Это может сделать Ваших коллег очень недовольными. И если Вы перераспределяете (который является, дают им), копия Вашей измененной команды, теперь у Вас есть лицензирование проблем (IANAL, но это может привести к судебным процессам).
  3. Возвращение к теме коллег, изменение команды, которая должна быть стандартной, могут повредить их рабочий процесс и путаницу со средой разработки.

Лучшее решение

Общее представление для того, когда Вы хотите иметь пользовательский флаг, состоит в том, чтобы иметь обертку вокруг исходной команды. Это может быть функцией в Вашем ~/.bashrc, скомпилированная программа, сценарий - безотносительно. Ключевой пункт - то, что это должно использоваться только в Вашей среде, и необходимо знать, когда Вы пишете команды для себя и когда Вы пишете для команд, которые будут использоваться другими.

Таким образом, вот некоторые опции/предложения:

  1. Определите функцию в Вашем ~/.bashrc. Функции имеют приоритет по командам, которые расположены в любом каталоге в Вашем PATH переменная.
  2. Именование должно быть однозначным. Например, именование Ваше собственное seq то же было бы неоднозначно, так как функциональность два будет отличаться. Лучший путь состоял бы в том, чтобы иметь my_seq или seq_f для функции. Сценарии обычно имеют .sh расширение, так, чтобы помог с неоднозначностью.
  3. При изменении скомпилированного двоичного файла позвольте ему жить в Вашем ~/bin и, возможно, переименуйте его.
  4. Рассмотреть использование ~/bin/mycommand вместо просто mycommand. Как сказано в презентации Hendrik Jan Thomassen, исходные команды Unix были коротки, потому что клавиши на старых терминалах PDP-11 было трудно нажать. Мы не должны волноваться о том в наше время, плюс то, если Вы помещаете ту команду в сценарий, это означает, что Вы не должны будете перепечатывать ее.

О комнате - пробный прогон

Coreutils GNU известны за отклонение функций, которые уже имеют определенные подобные реализации или могут быть достигнуты через объединение с другими утилитами; например, в df --no-header флаг отклоняется, потому что это может быть, покончили sed или другая утилита, которая может удалить первую строку текста. И это имеет смысл.

До rm идет, там уже существует -i флаг для интерактивного, таким образом, это должно предложить пользователю. Другая частая техника состоит в том, чтобы использовать echo вместо любой команды для пробного прогона. Таким образом --dry-run флаг мог быть реализован через:

# Prompts for y/n answer every time
rm -i ./*

# Automates answering "n"
for f in ./*; do rm -i "$f" <<< "n"; done

# or for non-bash shells:
for f in ./*; do echo "n" | rm -i "$f"; done

# prints the command that would be executed
echo rm "$file"

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

saferm(){
    case "$@" in
        *--dry-run*) echo rm "$@";;
        *) rm "$@";;
}

См. также

4
ответ дан 2 December 2019 в 01:27

Другие вопросы по тегам:

Похожие вопросы: