14

所以,我一直怀疑重定向在以下情况下的工作原理:

  1. 我输入“ls”,所有文件名都用空格分隔:

    test$ touch a b c
    test$ ls
    a b c
    
  2. 我使用“>”将 STDOUT 重定向到文件:

    test$ ls > ls.txt
    test$ cat ls.txt 
    a
    b
    c
    ls.txt
    

有趣的是,格式发生了变化,文件名由换行符分隔。似乎输出是由ls -1.

为什么后一种情况下的输出与前一种情况不同?ls 真的可以看到“>”符号,从而改变它的行为吗?

4

3 回答 3

11

ls测试其输出流以查看它是否是终端,并根据它修改其行为。

这是记录在案的;该man页面ls记录了取决于输出是否为终端的几件事:

  • 如果输出是终端,-C(对于多列输出)是默认值,否则-1(单列)是默认值。
  • 如果使用-lor-s并且输出是终端,则所有文件大小或块的总和分别打印在列表之前的一行上。
  • 如果输出是终端,-q则为默认值。这会将非图形字符打印为“?”。否则,-v-w是默认值。我有点不清楚-v和之间的区别-w。我的文档说-v强制“未经编辑打印非图形字符”和-w强制“原始打印不可打印字符”。</li>
于 2013-08-01T14:47:02.797 回答
3

它看不到符号(由 shell 解释),但它可以查明输出是否到终端。

为了将文件很好地组织到列中,ls需要知道终端的宽度。当输出设备不是终端时,它只是不知道如何格式化其输出。

这种行为的另一个很好的结果是你可以做一些事情,ls | wc -l而不用担心同一行上有多个文件。(不过,您仍然需要担心包含换行符的文件名。)

于 2013-08-01T14:49:07.937 回答
2

ls使用一个名为的内部变量,该变量ls_mode与 Gnu coreutils 实现的 3 ls“类型”命令不同。对于ls,它是LS_LS. 对于dir,它是LS_MULTI_COL,对于vdir,它是LS_LONG_FORMAT. 实际的ls 程序表明,根据这个变量,输出格式会发生变化。因为ls,这就是它所说的

如果 ls_mode 为 LS_LS,则输出格式取决于输出设备是否为终端。这是针对“ls”程序的。

这与您对格式随输出位置变化的经验一致。如果您尝试使用相同的dir方法,则不会。

于 2013-08-01T15:01:20.700 回答