Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为什么重定向符号会改变ls的行为?_Linux_Bash_Unix - Fatal编程技术网

Linux 为什么重定向符号会改变ls的行为?

Linux 为什么重定向符号会改变ls的行为?,linux,bash,unix,Linux,Bash,Unix,因此,我一直怀疑重定向在以下情况下如何工作: 我键入“ls”,所有文件名都用空格分隔: test$ touch a b c test$ ls a b c 我使用“>”将标准输出重定向到文件: test$ ls > ls.txt test$ cat ls.txt a b c ls.txt 有趣的是,格式发生了变化,文件名由换行符分隔。输出似乎是由ls-1生成的 为什么后一种情况下的输出与前一种情况下的输出不同?ls真的能看到“>”符号从而改变它的行为吗?ls测试它的输出流以确定它是

因此,我一直怀疑重定向在以下情况下如何工作:

  • 我键入“ls”,所有文件名都用空格分隔:

    test$ touch a b c
    test$ ls
    a b c
    
  • 我使用“>”将标准输出重定向到文件:

    test$ ls > ls.txt
    test$ cat ls.txt 
    a
    b
    c
    ls.txt
    
  • 有趣的是,格式发生了变化,文件名由换行符分隔。输出似乎是由
    ls-1
    生成的


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

    ls
    测试它的输出流以确定它是否是一个终端,并根据这一点修改它的行为

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

    • 如果输出是终端,
      -C
      (用于多列输出)是默认值,否则
      -1
      (一列)是默认值
    • 如果使用了
      -l
      -s
      ,且输出为终端,则在列表前的一行上分别打印所有文件大小或块的总和
    • 如果输出是终端,
      -q
      是默认值。这会将非图形字符打印为“?”。否则,
      -v
      -w
      是默认值。我不太清楚
      -v
      -w
      之间的区别。我的文档中说,
      -v
      强制“非图形字符的未编辑打印”,而
      -w
      强制“非可打印字符的原始打印”
    它看不到符号(由shell解释),但它可以确定输出是否发送到终端

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


    这种行为的另一个好结果是,您可以执行类似于
    ls | wc-l
    的操作,而不必担心同一行上有多个文件。(不过,您仍然需要担心包含换行符的文件名。)

    ls
    使用名为
    ls_mode
    的内部变量,这与Gnu coreutils实现的3个ls“type”命令不同。例如,它是
    LS\u LS
    。对于,它是
    LS\u MULTI\u COL
    ,对于,它是
    LS\u LONG\u格式
    。实际值表示根据此变量,输出格式将发生变化。对于
    ls
    ,它是这样说的

    如果ls_模式为ls_ls,则输出格式取决于 输出设备是一个终端。这是为“ls”计划准备的


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

    好问题。数百万人多年来一直在使用
    ls
    ,他们也在想同样的事情。如果你想在重定向输出中添加列,请尝试
    ls-C
    。基本上,是的
    ls
    使用了与
    [-T1]
    等效的代码,但由于
    ls
    是用C编写的,而不是用sh编写的,因此它使用了具有相同语义的不同构造。@YuFu它调用POSIX函数
    isatty
    (来自
    unistd.h
    ),这大概也是
    test
    在给定标志
    -t
    时调用的。对于GNU ls为True,对于具有相同行为的其他ls程序不一定为True。我不确定是否有任何其他
    ls
    实现具有这种行为。基于这个问题,我假设正在讨论的是GNU ls。IIRC,“Interactive 386/ix”上的ls也做了同样的事情,那是在Linux之前,但不是在GNU之前,而且很可能没有GNU ls(因为它是一个许可的SysV unix,等等)。谢谢。我不会往回走那么远。:)