grep无效

笨笨阿林
  • 272

执行如下命令:

ps aux|grep -n redis-server|grep -v grep

能正常找到redis-server的进程信息。
(注:grep -v grep是为了在结果中排除掉grep自身的进程信息)

但是写成别名:

alias pg="ps aux|grep -n $@|grep -v grep"

然后再执行:

pg redis-server

提示如下:

grep: redis-server: No such file or directory

请问是哪里错了?谢谢!

回复
阅读 2k
2 个回答
✓ 已被采纳

把顺序掉换一下就好了

alias pg='ps aux|grep -v grep| grep -n $@'

对于$@来讲, 符号后面的都是参数

$ alias pg="ps aux|grep -n $@|grep -v grep"
$ set -x  #开启bash调试模式
++ update_terminal_cwd
++ local url_path=
...

$ pg abc
+ ps aux
+ grep -n
+ grep -v grep abc
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
    [-e pattern] [-f file] [--binary-files=value] [--color=when]
    [--context[=num]] [--directories=action] [--label] [--line-buffered]
    [--null] [pattern] [file ...]
grep: abc: No such file or directory
++ update_terminal_cwd
++ local url_path= 

可以看出, pg abc执行的结果是

ps aux
grep -n
grep -v grep abc

即, grep -v grep 也是$@代表的一部分,被 bash 解析代入了.

其实你这样不行纯粹是因为你用了双引号,双引号在alias的时候已经将位置函数$@展开了,当然值就传递不进去了,不信你换成单引号试试....

锅了,锅了,确实不行哈,昨天晚上在家没法验证,有点想当然了。早上来公司了~那么来探究一下,为啥不生效吧。

在 bash 的 man 文档中关于位置参数有这样一句话:

The positional parameters are temporarily replaced when a shell function is executed (see Shell Functions).
当 shell 函数执行时,位置参数将被临时替换

也就是说,当没有调用函数时,位置变量始终是启动 bash 时传递的参数,默认是空值。

楼上老哥的回答中,不使用位置参数也同样生效

alias pg='ps aux|grep -v grep| grep -n'

如果想要使用位置参数,可以使用函数式写法,或利用函数写入别名,source之后直接使用

# .bashrc
pg(){ ps aux|grep -n $@ | grep -v grep; }
# 如果需要别名用法,同样利用函数调用
alias pg='f(){ ps aux | grep -n $@ | grep -v grep;}; f'

当然直接更换位置,向楼上老哥的写法也是 OK 的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏