代码之家  ›  专栏  ›  技术社区  ›  twisted

bash重定向到文件会添加意外的0A字节

  •  2
  • twisted  · 技术社区  · 4 年前

    我想如果我重新定向 对于一个文件,原本发送到控制台的字符序列将被写入该文件。

    为了测试这一点,我创建了3个文件,然后列出它们

    $ touch a b c
    $ ls
    a  b  c
    

    同样,这次重定向到一个我

    $ ls > out
    $ cat out
    a
    b
    c
    out
    

    意外的是,每个文件名输入输出之间都有一个0A换行符

    $ xxd out
    00000000: 610a 620a 630a 6f75 740a                 a.b.c.out.
    

    将ls的输出管道连接到xxd

    $ ls | xxd
    00000000: 610a 620a 630a 6f75 740a                 a.b.c.out.
    

    0A字节是如何到达那里的?做 ls 如果它被重定向,或者在某些情况下shell忽略换行符,行为会有所不同吗?

    $ lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description:    Ubuntu 20.04.3 LTS
    Release:    20.04
    Codename:   focal
    
    1 回复  |  直到 4 年前
        1
  •  2
  •   2e0byo    4 年前

    ls 如果被重定向,其行为将不同。您可以使用 -x

    $ mkdir /tmp/t
    $ cd /tmp/t
    $ touch a b c
    $ ls | cat
    a
    b
    c
    $ ls -x | cat
    a b c
    $ ls --format=single-column
    a
    b
    c
    

    我一直无法在手册页或快速谷歌上找到这方面的参考资料,但毫无疑问,会有人提供。这大概是为了使逐行迭代响应成为可能。我也从来没有注意到它,尽管依赖它很多次,现在我开始思考它!

    实施

        case LS_LS:
          /* This is for the `ls' program.  */
          if (isatty (STDOUT_FILENO))
            {
              format = many_per_line;
              /* See description of qmark_funny_chars, above.  */
              qmark_funny_chars = true;
            }
          else
            {
              format = one_per_line;
              qmark_funny_chars = false;
            }
          break;
    

    source

    或在当前gnu coreutils中:

      format = (0 <= format_opt ? format_opt
                : ls_mode == LS_LS ? (stdout_isatty ()
                                      ? many_per_line : one_per_line)
                : ls_mode == LS_MULTI_COL ? many_per_line
                : /* ls_mode == LS_LONG_FORMAT */ long_format);
    

    哪里 stdout_isatty 定义如前一示例中所示。

    source