Unix管道进入ls

66

直到现在我才认为我理解了*nix管道... 我有一个可执行文件叫做studio,它是链接到我安装的Android Studio的,并且我曾经认为我可以通过以下方式获得链接到的位置:

which studio | ls -l

但是那样行不通。它给出的结果相当于只在当前目录下运行了 ls -l 命令。

如果我运行 which studio,我会得到 /home/me/bin/studio 的路径。如果我运行 ls -l /home/me/bin/studio,我将得到所期望的输出,显示符号链接的位置。

那为什么管道版本不起作用呢?我对管道的理解还有什么需要掌握的吗?

3个回答

97

要做到这一点,您需要使用xargs

which studio | xargs ls -l

来自于man xargs

xargs - 从标准输入构建并执行命令行

要完全理解管道的工作原理,您可以阅读BASH中管道如何工作的简单说明?

Unix管道将第一个进程的STDOUT(标准输出)文件描述符连接到第二个进程的STDIN(标准输入)。然后发生的情况是,当第一个进程写入其STDOUT时,第二个进程可以立即从STDIN中读取该输出。


这在我尝试不带参数使用ls时似乎不起作用。因此,which studio | xargs ls只会输出which的结果。为什么需要参数才能工作? - bdbdbd
@bdbdbd 可能是因为ls $(which studio)完全相同。对which的输出进行ls操作不会给你除了路径之外的任何信息,而ls本身也只会给出路径信息。 - fedorqui

33

ls 不会从标准输入读取其参数,而是从命令行读取。要在命令行中获取目录,必须使用命令替换:

ls 不会从标准输入读取其参数,而是从命令行读取。要在命令行中获取目录,必须使用命令替换:

ls -l "$( which studio )"

(如果路径中可能包含空格,则需要双引号。)


4
使用 xargs 的答案更加简洁,但这并没有忽略我的Shell的颜色编码,这是一个很好的额外之处! - Dannid
@Dannid 当我尝试使用xargs时,我收到了“来自stdin的太多错误”的消息,但是这个答案对我非常有效。 - Salem
1
我该如何知道一个命令是从标准输入还是命令行读取其参数的呢? - Tengerye
3
@Tengerye:阅读其文档。 - choroba
@Tengerye 在描述部分的开头,man command。如果没有提到“读取标准输入”,那么很可能不支持该功能。 - Glastis

4

由于ls -l不接受任何输入,因此它对于which studio的输出不会有任何影响。这里重要的是理解标准输入和参数之间的区别。标准输入是一个特殊的文件,可以使用scanf过程(例如,在C程序中)进行读取,而程序的参数作为argvargc参数传递到主过程中。argv是一个由空字符终止的char数组的数组,而argc是该数组的长度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接