我想将文件的内容重定向到ls
命令输入:
ls -l < /home/john/1.txt
内容如下1.txt
:
/etc
我希望ls
列出文件中定义的目录的内容/home/jonh1.txt
- 即/etc
目录,但它似乎忽略了输入流 - 仍然列出当前目录的内容,而/etc
不是文件中定义的目录/home/jonh1.txt
。
答案1
它似乎忽略了输入流
是的。该ls
计划绝不使用输入流,因为它不是为从输入流读取任何内容而编写的。这不是任何 Unix 程序自动附带的功能 - 它必须单独实现。
不要混淆输入流 (stdin) 和命令行参数 (argv);前者是可以逐行读取的实际流,而后者是简单的只读字数组。在您的例子中,两者都存在且包含不同的数据。
(为什么它不应该对所有程序都自动执行?好吧,种类或者猫或者grep作为示例。这些程序接受不同类型的值 - 文件名作为参数,但文本作为 stdin 内容。因此,您可以将任何命令通过管道传输到| sort
,它会对输入进行排序。但如果 stdin 和命令行是同一件事,您就无法再通过管道传输任何内容,| sort
因为它会认为管道输入是文件名列表。反之亦然,您无法为其提供文件名,因为它只会对名称进行排序。)
如需了解其他观点,请参阅StackOverflow 上的这个解释(您已经在评论中得到)。
答案2
尝试使用 xargs:
xargs ls -l < /home/john/1.txt
答案3
如果您编写任何接受用户输入的命令行程序,您将非常清楚地看到发生了什么。如果程序有一个 read/readLine(不同的语言可能会给它不同的名称)语句,那么程序会提示用户输入,那么您也可以使用或将该输入管道化或|
重定向<
如果你看一下接受输入的程序,你会看到类似more
或less
,如果你键入它而不输入$more<ENTER>
,那么它会提示输入。通过将数据管道化给它,它会停止提示输入。如果我们运行没有参数的 sed,$sed<ENTER>
那么它肯定会出错,我们也不能这样做$echo abc|sed<ENTER>
。但是如果我们这样做$sed 's/a/b/'<ENTER>
,它会提示输入。这就是 echo abc|sed 's/a/b/'<ENTER>
工作原理。
如果您编写一个程序,即使像 Hello World 一样简单,但需要输入,例如程序提示输入一个单词,如果用户输入“abc”,它会显示“Hello abc”,您就会看到这一点。您将能够通过管道传输到该程序。无需任何额外的编程即可使管道和输入重定向正常工作。如果程序接受用户的键盘输入,则管道和重定向到该程序将正常工作,然后程序将不会提示输入。
答案4
编辑
正如 Kamil Maciorowski 在下面的评论中指出的那样,以下做法不是正确的。
如果
/home/john/1.txt
保证只包含一条路径,则你绝对应该双引号。如果文件可能包含多个路径,并且您故意依赖于分词,那么这不是提供任意路径的正确方法。
原始帖子(不好的例子)
您可以使用以下内容:
ls -l $(cat /home/john/1.txt)
请参阅> man bash
章节命令替换。