grep无效

执行如下命令:

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

请问是哪里错了?谢谢!

阅读 838
评论 更新于 2018-11-30
    2 个回答
    Yujiaao
    • 10.3k

    把顺序掉换一下就好了

    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 解析代入了.

    评论 赞赏 2018-12-02
      其实你这样不行纯粹是因为你用了双引号,双引号在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 的。

      评论 赞赏 2018-12-04
        撰写回答

        登录后参与交流、获取后续更新提醒