当我创建时
alias wd='ps -ef | grep java | awk {'print $2 " " $9'} | egrep "(A|B|C|D)"'
或者
function wd () {
ps -ef | grep java | awk '{print $2}' ...
}
在我的 .bashrc 文件中,出现错误。有趣的是,如果我使用该函数获取 .bashrc 文件,它会“编译”,但在执行时会给出:
context is
>>> \ <<< {\print
missing }
有人可以帮我解决这个问题,并回答什么时候将某些内容放在函数中而不是放在别名中更好吗?
答案1
为什么别名不起作用
alias wd='ps -ef | grep java | awk {'print $2 " " $9'} | egrep "(A|B|C|D)"'
该alias
命令接收三个参数。第一个是字符串wd=ps -ef | grep java | awk {print
(单引号防止它们之间的字符具有特殊含义)。第二个参数由单个空格字符组成。 (在 中.bashrc
,位置参数$2
和$9
为空,因此$2
扩展为包含 0 个单词的列表。)第三个参数是} | egrep "(A|B|C|D)"
(单引号再次保护特殊字符)。
当遇到别名定义时,它会像任何其他 shell 命令一样被解析。然后在扩展别名时解析为别名定义的字符串。以下是定义此别名的一些可能方法。第一种可能性:由于整个别名定义在单引号内,因此仅在命令中使用双引号,这意味着您必须使用反斜杠保护 awk 的"
and 。$
alias wd='ps -ef | grep java | awk "{print \$2 \" \" \$9}" | egrep "(A|B|C|D)"'
第二种可能性:每个字符在单引号内代表其自身,除了单引号结束文字字符串。'\''
是“单引号字符串中的单引号”的惯用语:结束单引号字符串,放入文字单引号,然后立即开始一个新的单引号字符串。由于没有中间的空格,它仍然是同一个词。
alias wd='ps -ef | grep java | awk '\''{print $2 " " $9}'\'' | egrep "(A|B|C|D)"'
你可以稍微简化一下:
alias wd='ps -ef | grep java | awk '\''{print $2, $9}'\'' | egrep "(A|B|C|D)"'
提示:用于set -x
查看 shell 如何扩展您的命令。
为什么该功能不起作用
我不知道。你展示的部分看起来不错。如果您在我的解释后仍然不明白为什么您的函数不起作用,请复制粘贴您的代码。
别名还是函数?
仅在非常简单的情况下才使用别名,通常是为常用命令提供较短的名称或提供默认选项。例子:
alias grep='grep --color'
alias cp='cp -i'
alias j=jobs
对于更复杂的事情,请使用函数。
你应该写什么
不要解析输出,而是ps
让它生成适合您的输出。
wd () {
ps -C java -o pid=,cmd= | egrep "(A|B|C|D)"
}
答案2
别名的问题在于引号不能直接嵌套(除了作为特殊情况,在 内部$()
)。你需要逃离内心的束缚。
alias wd='ps -ef | grep java | awk {\'print $2 " " $9\'} | egrep "(A|B|C|D)"'
# ^^ ^^
你已经删除了太多的函数形式,我无法确定,但错误片段来自awk
并建议引用或 shell 变量扩展问题。
一般来说,函数比别名更灵活(除了历史扩展之外,您无法控制使用别名的参数处理),但别名要快一些,如果您以空格结束别名,则第一个参数将扩展为命令(制表符补全等)别名在声明它们的文件中也不起作用(以避免无限别名扩展循环)。
答案3
我认为您不能将参数传递给别名。别名只是命令第一个单词的字符串替换规则。
例子:
alias wd='ps -ef | grep java | awk {'print $2 " " $9'} | egrep "(A|B|C|D)"'
将导致命令wd arg1 arg2 arg3
被替换并执行为
ps -ef | grep java | awk {'print " " '} | egrep "(A|B|C|D)" arg1 arg2 arg3
对于除此之外的所有事情,请使用函数。