我是 bash 函数的新手,但刚刚开始编写一些零碎的东西来加快我的工作流程。我喜欢在进行过程中测试这个,所以我发现自己经常编辑和采购我的 ~/.profile 并且发现~/.输入有点尴尬......
所以我想我要做的第一件事是:
sourceProfile(){
source ~/.profile
}
editProfile(){
vim ~/.profile && sourceProfile
}
Run Code Online (Sandbox Code Playgroud)
运行 editProfile 时,我在 sourceProfile 调用中遇到问题。最初我收到错误:
-bash: ~./profile: No such file or directory
Run Code Online (Sandbox Code Playgroud)
请注意我的函数中没有错字!
但是,如果我使用别名,它会起作用。
alias sourceProfile='source ~/.profile'
Run Code Online (Sandbox Code Playgroud)
但是,在添加该别名然后将其注释掉并取消注释该函数后,我开始收到语法错误:
-bash: /home/jonathanramsden/.profile: line 45: syntax error near unexpected token `('
-bash: /home/jonathanramsden/.profile: line 45: `sourceProfile(){'
Run Code Online (Sandbox Code Playgroud)
程序是:
alias sservice='sudo service'
Run Code Online (Sandbox Code Playgroud)
我很确定我所做的只是评论/取消评论!根据我的谷歌搜索,这似乎是定义函数的语法。
别名就像某种形式的宏扩展,类似于在 C 中完成的预处理,#define除了在 shell 中,预处理阶段和解释阶段之间没有清晰明显的界限(此外,别名不会在所有上下文中扩展并且可以像嵌套别名一样进行多轮别名扩展)。
当你这样做时:
alias sourceProfile='source ~/.profile'
sourceProfile() {
something
}
Run Code Online (Sandbox Code Playgroud)
别名扩展将其变成:
source ~/.profile() {
something
}
Run Code Online (Sandbox Code Playgroud)
这是一个语法错误。和:
alias sourceProfile='source ~/.profile'
editProfile(){
vim ~/.profile && sourceProfile
}
Run Code Online (Sandbox Code Playgroud)
把它变成:
editProfile(){
vim ~/.profile && source ~/.profile
}
Run Code Online (Sandbox Code Playgroud)
所以,如果你以后重新定义sourceProfile为一个函数,editProfile就不会调用它了,因为 的定义editProfile具有原始别名的扩展值。
此外,对于函数(或任何复合命令),别名仅在函数定义时(在读取和解析时)展开,而不是在运行时展开。所以这:
editProfile(){
vim ~/.profile && sourceProfile
}
alias sourceProfile='source ~/.profile'
editProfile
Run Code Online (Sandbox Code Playgroud)
不会工作,因为sourceProfile在editProfile解析函数体时没有定义,并且在运行editProfile函数时不会有任何别名扩展。
所以,避免混用别名和函数。并注意使用别名的含义,因为它们不是真正的命令,而是某种形式的宏扩展。