在Bash中如何将printf的输出传递给ls命令?

4

所以我正在学习bash中的管道,我找到了这个简洁的描述:

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

来源

在此理解的基础上,让我们将printf的STDOUT连接到ls的STDIN。为简单起见,打印父目录(printf ..)。

~/Desktop/pipes$ mkdir sub
~/Desktop/pipes$ ls
sub
~/Desktop/pipes$ cd sub
(no files)
~/Desktop/pipes/sub$ printf .. | ls
(no files)
~/Desktop/pipes/sub$ 

我想要执行:ls ..,但似乎我只得到了ls。为什么会这样?如何使用管道符号列出父目录下的文件?我是否误解了管道符号?

2
ls 不从标准输入读取。因此,ls .. 是在这里获取您想要的内容的方法。man ls 是您的好朋友。 - codeforester
那么这只是ls的属性吗?否则,我对管道的理解是正确的吗?ls ..没有从标准输入中获取..参数吗? - Kenny Worden
你需要使用 xargs 命令与 ls 命令结合。@KennethWorden - Inian
1
是的,这是 ls 的一个属性,它不会从标准输入读取参数(因此管道不会产生任何效果)。 - Sir Athos
2个回答

3

许多程序不仅仅是ls,不从stdin读取内容。同样可能的是,某个程序也不会向stdout输出内容。

以下实验可以帮助您更好地理解。请按照以下步骤进行:

cat > file1
This is file1
^D

^D是您按下的<CTRL>+D,它是默认的文件结尾标志。因此,首先我们调用cat程序,并将其stdout重定向到file1。如果您没有提供输入文件名,则会从stdin读取,因此我们键入“This is file1”。

现在进行类似操作:

cat > file2
This is file2
^D

现在,如果您:
cat < file1

你将获得:

This is file1

如果您遇到以下情况:
cat file1 | cat file2

或者:

cat file2 < file1

为什么?因为如果提供输入文件名,cat程序就不会像ls一样读取stdin

现在,考虑以下内容:

cat - file1 < file2

按照惯例,- 表示标准流,即读取时的 stdin 或写入时的 stdout

2
问题在于ls并没有像你期望的那样从stdin读取。你需要使用一个能够从stdin读取的工具,例如xargs,并将读取的输入传递给ls
printf "someSampleFolderOrFile" | xargs ls 

xargs man 页面,

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


我的问题更多地是关于管道如何工作的,但无论如何感谢你的回答。 - Kenny Worden

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