我是 bash 函数的新手,但刚刚开始编写一些零散的内容来加快我的工作流程。我喜欢在进行过程中对此进行测试,所以我发现自己经常编辑和获取我的 ~/.profile 并发现~/.
打字有点尴尬......
所以我想我要做的第一件事如下:
sourceProfile(){
source ~/.profile
}
editProfile(){
vim ~/.profile && sourceProfile
}
运行 editProfile 时,我在 sourceProfile 调用上遇到问题。最初我收到错误:
-bash: ~./profile: No such file or directory
请注意我的函数中没有拼写错误!
但是,如果我使用别名,它就会起作用。
alias sourceProfile='source ~/.profile'
但是,在添加该别名然后将其注释掉并取消注释该函数后,我开始收到语法错误:
-bash: /home/jonathanramsden/.profile: line 45: syntax error near unexpected token `('
-bash: /home/jonathanramsden/.profile: line 45: `sourceProfile(){'
行是:
alias sservice='sudo service'
我很确定我所做的只是评论/取消评论!根据我的谷歌搜索,这似乎是定义函数的语法。
答案1
别名就像某种形式的宏扩展,类似于 C 中的预处理,#define
只是在 shell 中,预处理阶段和解释阶段之间没有清晰可见的界限(而且,别名不会在所有上下文中扩展)并且可以有几轮别名扩展,就像嵌套别名一样)。
当你这样做时:
alias sourceProfile='source ~/.profile'
sourceProfile() {
something
}
别名扩展将其变成:
source ~/.profile() {
something
}
这是一个语法错误。和:
alias sourceProfile='source ~/.profile'
editProfile(){
vim ~/.profile && sourceProfile
}
将其变成:
editProfile(){
vim ~/.profile && source ~/.profile
}
所以,如果你以后重新定义sourceProfile
为函数,editProfile
就不会调用它,因为 的定义editProfile
具有原始别名的扩展值。
此外,对于函数(或任何复合命令),别名仅在函数定义时间(当它们被读取和解析时),而不是在运行时。所以这:
editProfile(){
vim ~/.profile && sourceProfile
}
alias sourceProfile='source ~/.profile'
editProfile
不起作用,因为sourceProfile
在解析函数体时尚未定义editProfile
,并且在运行函数时不会有任何别名扩展editProfile
。
因此,避免混合别名和函数。并警惕使用别名的影响,因为它们并不是真正的命令而是某种形式的宏观扩张。
答案2
当开发测试函数时,请确保在source
每次编辑之间重新加载 () 函数定义,否则旧的函数定义仍将处于活动状态。您的函数中没有拼写错误,并且您不应该收到该错误消息(我无法在此处重现它),这意味着您没有按照编写的方式运行该函数。
另外,我建议您开始使用$HOME
而不是~
在编写脚本时使用,主要是因为~
它的行为根本不像变量(请参阅为什么波形符 (~) 不在双引号内展开?)。
建议:
edit_profile () {
local EDITOR=${EDITOR:-vim}
local file="$HOME/.profile"
"$EDITOR" "$file" && source "$file"
}
该file
变量是额外的,但该EDITOR
变量可能已设置为合理的编辑器。如果不是,代码将其设置为vim
。