Zac*_*Zac 8 shell bash function
这是我的代码:
function update_profile
{
echo "1. Update Name"
echo "2. Update Age"
echo "3. Update Gender"
echo "Enter option: "
read option
case $option in
1) update_name ;;
2) update_age ;;
3) update_gender ;;
esac
function update_name
{
echo "Enter new name: "
read name
}
}
Run Code Online (Sandbox Code Playgroud)
只是想确定是否可以这样做。我确实知道我可以将所有代码都放入案例中,但这会很混乱,所以我想在一个函数中创建一个独立的函数,并在需要执行其命令时调用。
jhe*_*ran 13
是的,这是可能的。
甚至可以将一个函数嵌套在另一个函数中,尽管这不是很有用。
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.
Run Code Online (Sandbox Code Playgroud)
来源:Linux 文档项目
是的,当您考虑 shell 函数的真正含义时,这一点就会变得更加清楚。
对于 POSIX 兼容的 shell,函数定义是标准化的:
2.9.5功能定义命令
fname() compound-command[io-redirect ...]
该函数被命名为fname... 实现应为函数和变量维护单独的名称空间。
参数compound-command表示复合命令,如复合命令中所述。
compound-command<<&io-redirect&>${expansions}<<&io-redirect&>variable=assignmentscompound-command因此,从本质上讲,名为 的 shell 函数fname是一个由至少一个复合命令组成的文字字符串,shell 将从内存中调用该复合命令,并在fname它出现在命令位置的输入中时执行- 这意味着无论cmd将在何处执行做。这个定义为在 POSIX shell 中使用函数提供了很多可能性。以下任一情况均可接受:
fn() {
command; list;
fn() { : redefines itself upon first execution; }
}
Run Code Online (Sandbox Code Playgroud)
...和...
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
}
Run Code Online (Sandbox Code Playgroud)
但这只是一个小例子。如果您考虑复合命令的含义,您可能会开始发现传统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
Run Code Online (Sandbox Code Playgroud)
除此之外还有其他人。上述任何一项都应该像...
fname() compound list
Run Code Online (Sandbox Code Playgroud)
...并且其中任何可以在未分配为函数时嵌套的内容仍然可以嵌套,即使定义为命令也是如此。
这是我编写函数的一种方法:
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
Run Code Online (Sandbox Code Playgroud)
关于上述内容的一些注意事项:
read更新受 IFS 和反斜杠解释的约束。很可能是这样IFS= read -r "$1",但我不确定你希望如何解释这些事情。在此网站上查找其他答案,以获得有关该分数的更多更好的信息。printf '\033%s...文档中的 假设/dev/tty链接到 VT100 兼容终端,在这种情况下,使用的转义应该阻止此处文档的最终换行符显示在屏幕上。鲁棒地tput会被使用。在那里获取man termcap更多信息。
printf,也tput可以直接在此处文档中输入转义字符,例如^V{esc}[A^V{esc}@where是表示组合键的^V一种方式,并且是键盘的键。CONTROL+V{esc}ESC上面的函数将根据其参数集执行双重任务 - 它将执行两次并仅根据需要重新评估其提示 - 因此它不需要第二个函数 - 因为只要最初调用它,它就可以执行这两项操作首先没有参数。
所以如果我跑...
update_prof; printf %s\\n "$name"
Run Code Online (Sandbox Code Playgroud)
随后的终端活动如下所示:
1. Update Name
2. Update Age
3. Update Gender
Enter option: 1
Enter name: yo mama
yo mama
Run Code Online (Sandbox Code Playgroud)
您可以在 shell 需要命令的任何地方定义函数,包括在函数中。请注意,该函数是在 shell 执行其定义时定义的,而不是在 shell 解析文件时定义的。所以如果用户第一次update_profile执行时选择选项1,你的代码将无法工作,因为update_name在语句中调用when时case,函数的定义update_name还没有被执行。一旦该函数update_profile被执行一次,该函数update_name也将被定义。
您需要将 的定义移到update_name使用它的位置之前。
定义update_nameinsideupdate_profile并不是特别有用。这确实意味着update_name在第一次执行之前不会被定义update_profile,但之后它将保持可用。如果您update_name只想在内部可用update_profile,请在其中定义函数并unset -f update_name在从函数返回之前调用。不过,与做简单的事情并全局定义所有函数相比,这样做并不会真正获得任何好处。
| 归档时间: |
|
| 查看次数: |
10785 次 |
| 最近记录: |