我正在寻找一种方法来使用命令的输出(比如command1)作为另一个命令的参数(比如command2)。
我在尝试grep
who
命令的输出时遇到了这个问题,但是使用了另一组命令(实际tty
管道传输到sed
)给出的模式。
如果tty
显示:
/dev/pts/5
who
显示:
root pts/4 2012-01-15 16:01 (xxxx)
root pts/5 2012-02-25 10:02 (yyyy)
root pts/2 2012-03-09 12:03 (zzzz)
我只想要关于“pts / 5”的行
所以我将tty
传递给sed
,如下所示:
$ tty | sed 's/\/dev\///'
pts/5
尝试以下命令不起作用:
$ who | grep $(echo $(tty) | sed 's/\/dev\///')"
我发现以下工作正常:
$ eval "who | grep $(echo $(tty) | sed 's/\/dev\///')"
但我确信可以避免使用eval
。
作为最后的一个节点:我注意到who
的“-m”参数给了我我想要的内容(只获取链接到who
的行当前用户)。但是我仍然很好奇如何将管道和命令嵌套组合起来......
答案 0 :(得分:10)
通常使用xargs使一个命令的输出成为另一个命令的选项。例如:
$ cat command1
#!/bin/sh
echo "one"
echo "two"
echo "three"
$ cat command2
#!/bin/sh
printf '1 = %s\n' "$1"
$ ./command1 | xargs -n 1 ./command2
1 = one
1 = two
1 = three
$
但是......虽然那是你的问题,但这并不是你真正想知道的。
如果您不介意将tty存储在变量中,可以使用bash变量修改来进行替换:
$ tty=`tty`; who | grep -w "${tty#/dev/}"
ghoti pts/198 Mar 8 17:01 (:0.0)
(你想要-w因为如果你在pts / 6上你不应该看到pts / 60的登录。)
您只能在变量中执行此操作,因为如果您尝试将tty
命令放入管道中,它会认为它不再与终端关联运行。
$ true | echo `tty | sed 's:/dev/::'`
not a tty
$
请注意,到目前为止,此答案中没有任何内容特定于bash。由于您正在使用bash,另一种解决此问题的方法是使用进程替换。例如,虽然这不起作用:
$ who | grep "$(tty | sed 's:/dev/::')"
这样做:
$ grep $(tty | sed 's:/dev/::') < <(who)
答案 1 :(得分:6)
@ Eduardo的回答是正确的(当我写这篇文章时,已经出现了其他一些好的答案),但我想解释为什么原始命令失败了。像往常一样,set -x
对于了解实际发生的情况非常有用:
$ set -x
$ who | grep $(echo $(tty) | sed 's/\/dev\///')
+ who
++ sed 's/\/dev\///'
+++ tty
++ echo not a tty
+ grep not a tty
grep: a: No such file or directory
grep: tty: No such file or directory
上面并没有完全明确,但正在发生的是tty
正在输出“不是tty”。这是因为它是管道的一部分被输入who
的输出,所以它的标准输入确实不是tty。这是其他人的答案工作的真正原因:他们从管道中获取tty
,因此它可以看到您的实际终端。
echo $(tty)
,它与tty
基本相同。
答案 2 :(得分:5)
你可以在Bash variable mangling的帮助下不使用sed来做到这一点,尽管@ruakh指出这在单行版本中不起作用(没有用分号分隔命令)。我要离开这第一个方法了,因为我觉得有趣的是它不能在一行中起作用:
TTY=$(tty); who | grep "${TTY#/dev/}"
首先将tty
的输出放入变量中,然后在grep使用它时删除前导/dev/
。但是,在bash为grep执行变量扩展/修改的时候,如果没有分号TTY
在环境中不。
这是一个可行的版本,因为它使用已修改的环境(具有TTY
)生成子shell:
TTY=$(tty) WHOLINE=$(who | grep "${TTY#/dev/}")
结果保留在$WHOLINE
。
答案 3 :(得分:2)
你可以这样做:
tid=$(tty | sed 's#/dev/##') && who | grep "$tid"