别名或 bash 函数不起作用

别名或 bash 函数不起作用

当我创建时

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

对于除此之外的所有事情,请使用函数。

相关内容