Отключить один флаг команды и бесконечную рекурсию

Если вы используете bash в качестве оболочки, вы можете нажать Ctrl-X Ctrl-E , чтобы открыть редактор (определено с помощью $ VISUAL или $ EDITOR, например vi или, возможно, nano ).

Затем вы можете вставлять туда свои команды точно так же, как если бы вы редактировали файл. Они будут выполнены, если вы сохраните и выйдете. Или отменяется, если выйти без сохранения.

2
02.03.2018, 21:02
1 ответ

Вы можете переопределить встроенную -команду, внешнюю команду или функцию с псевдонимом. Пока псевдоним выполняется, псевдоним с таким же именем не будет расширен. Таким образом, если расширение псевдонима использует имя псевдонима, это вызывает встроенную -или внешнюю команду или функцию с тем же именем. Это означает, что вы можете использовать псевдоним простым способом для передачи дополнительных параметров команде. Но вы не можете сделать намного больше из-за того, как работает расширение псевдонима — это простая замена слов без оценки.

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

В оболочках POSIX вы можете заставить имя ссылаться на встроенную -внутреннюю или внешнюю команду, поместив commandперед вызовом. Другими словами, commandигнорирует псевдонимы и функции. В zsh commandвызывает вызов внешней команды (, если не установлена ​​опция posix_builtins), т. е. также обходит встроенные функции. Чтобы принудительно выполнить встроенную команду zsh, используйте встроенную команду builtin.

Это приводит к одному решению :в вашей функции-оболочке: вызовите builtin fcвместо fc.

Однако это не обязательно лучшее решение в вашем случае, потому что ваша функция будет вызываться везде, включая вызовы fcиз других функций. При переопределении встроенного поведения -я рекомендую придерживаться псевдонима. Псевдоним применяется только к тому, что вы вводите в командной строке или загружаете с помощью .(, также известного как source), а не к функциям, загружаемым с помощью autoload -U(, что является рекомендуемым способом автоматической загрузки функции ). Поэтому определите псевдоним fc, который вызывает вашу функцию-оболочку, и дайте вашей функции-оболочке другое имя.

fc_wrapper () {
    for x; do
        if [[ "${x}" == -*W* ]]; then
            echo >&2 "I'm sorry Dave. I'm afraid I can't do that."
            return 1
        fi
    done
    \fc "${@}"
}
alias fc=fc_wrapper

Я поставил \fcвместо fcв определении функции. В этом нет необходимости при загрузке определения из .zshrcперед определением псевдонима, но это необходимо, например, если вы редактируете или перезагружаете определение функции во время интерактивного сеанса. Я также сделал несколько незначительных улучшений функции :

.
  • Печатать сообщение об ошибке при стандартной ошибке.
  • Если вы не выполняете задание, верните статус ошибки.
  • Также ловите такие случаи, как fc -WI. Это не полностью надежно, так как он также будет перехватывать такие вызовы, какfc -R -- -W(чтение истории из файла с именем -W), но этого вполне достаточно для данного случая использования.
3
27.01.2020, 21:55

Теги

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