В энергии просто нажимают * для поиска вперед... # будет искать назад.
О: предварительно ожидайте * и # с g, чтобы также распознать частичные слова.
Да, возможно.
Еще можно гнездиться функцией в другой функции, хотя это не очень полезно.
f1 ()
{
f2 () # nested
{
echo "Function \"f2\", inside \"f1\"."
}
}
f2 # Gives an error message.
# Even a preceding "declare -f f2" wouldn't help.
echo
f1 # Does nothing, since calling "f1" does not automatically call "f2".
f2 # Now, it's all right to call "f2",
#+ since its definition has been made visible by calling "f1".
# Thanks, S.C.
Источник: Проект документации Linux
Вы можете определить функцию в любом месте оболочки ожидает команды, в том числе в функции. Обратите внимание, что в данный момент определена функция, которую оболочка выполняет его определение, а не когда оболочка анализирует файл. Таким образом, ваш код не будет работать, если пользователь выбирает вариант 1 в первый раз UPDATE_PROFILE
, потому что, когда COMPLATE_NAME
вызывается в операторе
, определение функции update_name
пока не будет выполнен. Как только функция update_profile
выполнена один раз, также будет определена функция update_name
.
Вам необходимо переместить определение UPDATE_NAME
до того, как она используется.
Определение UPDATE_NAME
Внутри update_profile
не особенно полезно. Это означает, что UPDATE_NAME
не будет определено до первого раз update_profile
, но он останется доступен впоследствии. Если вы хотите UPDATE_NAME
, чтобы быть доступным только внутри update_profile
, определите функцию внутри него и вызовите Unset -f update_name
Перед возвратом из функции. Вы действительно ничего не получите, делая это, хотя по сравнению с простым вещью и определением всех функций глобально.
Да, и это становится яснее, когда вы считаете, что действительно функция оболочки.
Для SOXIX-совместимых оболочек определение функции стандартизируется таким образом:
2.9.5 Команда определения функции
FNAME () Соединение-команда [IO-Redirect ...]
Функция называется fname
... Реализация должна поддерживать отдельные названные пространства для функций и переменных .
Аргумент Communic Command представляет собой составную команду , как описано в составных командах .
Commual Command
или << & IO-Redirect &>
; Все $ {Expansions}
должны выполняться как обычные каждый раз, когда вызывается функция. Аналогично, необязательно << & IO-Redirect &>
перенаправления и любые переменные = назначения
в пределах соединения Comment
должны выполняться во время выполнения самой функции, а не определение функции. См. Последствия ошибок оболочки Для последствий сбоев этих операций на интерактивных и неинтерактивных оболочках. И вот в своем сердце функция оболочки имена fname
, является буквальной строкой, состоящей из хотя бы одного COMBENT COMMENT , что оболочка вызовет из памяти и выполняется на месте Из Fname
, когда это происходит в входе в командной позиции - что означает, где будет делать CMD . Это определение открывает много возможностей для использования функции в оболочке POSIX. Любое из следующего является приемлемым:
fn() {
command; list;
fn() { : redefines itself upon first execution; }
}
... и ...
fn() {
helper1() { : defines another function which it can call; }
helper2() { : and another; }
helper1 "$@" | helper2 "$@" #processes args twice over pipe
command "$@"; list; #without altering its args
}
Но это небольшой пример. Если вы рассматриваете значение Communic Command , вы можете начать видеть, что обычное Fn () {: CMDS; }
Форма только в одну сторону функция может работать. Рассмотрим некоторые различные виды составных команд:
{ compound; list; of; commands;} <>i/o <i >o
(subshelled; compound; list; of; commands) <>i/o <i >o
if ...; then ...; fi <>i/o <i >o
case ... in (...) ...;; esac <>i/o <i >o
for ... [in ... ;] do ...; done <>i/o <i >o
(while|until) ...; do ....; done <>i/o <i >o
и другие, кроме. Любой из вышеперечисленных должен работать как ...
fname() compound list
... и из числа тех, кто может быть вложен, когда не назначен как функция, все еще может быть вложена, даже если она определяется как команда.
Вот один из способов написать вашу функцию:
update_prof(){
cat >&3
read "${2-option}" <&3
case "${1-$option}" in
1) update_prof '' name ;;
2) update_prof '' age ;;
3) update_prof '' gender ;;
*) unset option ;;
esac
} <<-PROMPT 3<>/dev/tty
${1-
1. Update Name
2. Update Age
3. Update Gender
}
Enter ${2:-option}: $(
printf '\033%s' \[A @
)
PROMPT
Некоторые заметки о вышеупомянутых:
Чтение
в обновлении подлежит интерпретации IFS и интерпретации обратной кости. Оценительно это может быть IFS = Read -R «$ 1»
, но я не уверен, как вы хотите, чтобы эти вещи были интерпретированы. Ищите другие ответы на этом сайте для более и лучшей информации по этому результату. Printf '\ 033% S ...
в здесь предполагается / dev / tty
связано с совместимым клемма VT100, в этом случае используемое место Сохраняйте окончательную новую строку здесь доктора от отображения на экране. Устойчивая TUTP
будет использоваться. Сделайте MAN TERMCAP
для получения дополнительной информации.
PrintF
, либо TPUTPUT
, введя символы Escape буквально в документ здесь ^ v {esc } [A ^ V {Esc} @
Где ^ v
- способ представления комбинации клавиш + V
и {ESC}
Клавиша клавиатуры esc
. Вышеуказанная функция будет тянуть двойную погрузку в зависимости от его набора параметров - он будет выполняться дважды и переоценивать его подсказку только по мере необходимости - и поэтому ему не нужна вторая функция - потому что она может сделать оба изначально называется без параметров в первую очередь.
Итак, если я бегу ...
update_prof; printf %s\\n "$name"
Внужденная терминальная активность выглядит как:
1. Update Name
2. Update Age
3. Update Gender
Enter option: 1
Enter name: yo mama
yo mama
Я повторно -добавляю сюда свой ответ, который Джефф Шаллер удалил, чтобы убедиться, что есть ответ, который показывает, что действительно существует вариант использования, и по своей сути неправильно говорить «это не очень полезно», на что намекает принятый ответ.
Вот еще раз (исправлено, чтобы показать, что я имею в виду под ответом):
Это "не очень полезно"? Я думаю, что это на самом деле довольно круто.
У меня есть специальные функции инициализации проекта -в моих bashrc
/ bash_aliases
, которые инициализируют мою среду для данного проекта.
До этого у меня были глобально определены все псевдонимы и функции (ярлыки, такие как cdprojectname
и modulename_build
и подобные ). Проблема в том, что вы можете легко использовать очень длинные имена, чтобы избежать конфликтов имен после работы над большим количеством проектов.
Итак, что я сделал, так это то, что я взялcdprojectname
(вроде cdsd
для проекта sd
), и это функция, которая не только переходит в каталог проекта, но и инициализирует всю мою среду разработки, когда дело доходит до проекта..
По моему мнению, это круто, что вы можете создать функцию, определяющую функции оболочки. Однако нужно будет проверить, работает ли это, когда я использую свои псевдонимы изнутри vim
cdsd
из vim сейчас -все еще крутая функция, как она есть! "Please don't add "thank you" as an answer. Once you have sufficient reputation, you will be able to vote up questions and answers that you found helpful. – Jeff Schaller"
Извините, у меня нет возможности написать вам, но я не написал то, что написал в качестве благодарности, но я видел из более ранних комментариев/ответов, которые не особо освещают возможный вариант использования для этого, некоторые даже говорят " Можно даже вложить функцию в другую функцию, хотя это не очень полезно "
Это не благодарность, но хочу отметить, что вместо «это не очень полезно» это на самом деле «действительно -действительно полезная и удобная функция», которая была бы полезна для других языков сценариев/оболочек. есть на самом деле!
Я опубликовал свой ответ, потому что категорически не согласен с тем, что это не очень полезно, но принятый в настоящее время ответ намекает на это... пожалуйста, отредактируйте так, как хотите, или просто сохраните его, иначе в принятом ответе есть ложная информация/подсказка I думать.