AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 519782
Accepted
exit_status
exit_status
Asked: 2019-05-20 02:34:24 +0800 CST2019-05-20 02:34:24 +0800 CST 2019-05-20 02:34:24 +0800 CST

在没有文件描述符副本的情况下将 stdout 和 stderr 重定向到同一个文件是否安全?

  • 772

我从空目录开始。

$ touch aFile
$ ls
aFile

然后我ls有两个参数,其中一个不在此目录中。我将两个输出流重定向到一个名为output. 我使用>>是为了避免同时写。

$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile

这似乎有效。这种方法有什么危险吗?

io-redirection stdout
  • 3 3 个回答
  • 2491 Views

3 个回答

  • Voted
  1. Kusalananda
    2019-05-20T03:17:04+08:002019-05-20T03:17:04+08:00

    当你这样做时会发生什么

    some_command >>file 2>>file
    

    是那file将被打开以追加两次。这在 POSIX 文件系统上是安全的。在打开文件进行追加时发生的任何写入都将发生在文件的末尾,无论数据是来自标准输出流还是标准错误流。

    这依赖于对底层文件系统中原子追加写入操作的支持。某些文件系统,例如 NFS,不支持原子追加。参见 StackOverflow 上的问题“文件附加在 UNIX 中是原子的吗?”。

    使用

    some_command >>file 2>&1
    

    即使在 NFS 上也可以工作。

    但是,使用

    some_command >file 2>file
    

    不安全,因为 shell 会截断输出文件(两次),并且任何一个流上发生的任何写入都将覆盖另一个流已经写入的数据。

    例子:

    $ { echo hello; echo abc >&2; } >file 2>file
    $ cat file
    abc
    o
    

    首先hello写入字符串(带有终止换行符),然后abc从标准错误写入后跟换行符的字符串,覆盖hell. 结果是abc带有换行符的字符串,然后是第一个echo输出的剩余部分,ano和换行符。

    在输出文件中交换两个echo缠绕hello的结果,因为该字符串最后写入并且比abc字符串长。重定向发生的顺序无关紧要。

    使用更惯用的会更好,更安全

    some_command >file 2>&1
    
    • 22
  2. Best Answer
    mosvy
    2019-05-20T08:43:58+08:002019-05-20T08:43:58+08:00

    不,它不只是像标准一样安全>>bar 2>&1。

    当你写作

    foo >>bar 2>>bar
    

    您使用bar两次打开文件O_APPEND,创建两个完全独立的文件对象[1],每个对象都有自己的状态(指针、打开模式等)。

    2>&1这与仅调用系统调用非常不同dup(2),并使同一文件对象的 stderr 和 stdout 可互换别名。

    现在,有一个问题:

    O_APPEND如果多个进程一次将数据附加到文件,可能会导致 NFS 文件系统上的文件损坏。这是因为 NFS 不支持附加到文件,所以客户端内核必须模拟它,这在没有竞争条件的情况下无法完成。

    您通常可以指望文件同时从两个不同的地方写入的概率很低bar。foo >>bar 2>&1但是被你的>>bar 2>>bar你只是增加了十几个数量级,没有任何理由。

    [1] POSIX 术语中的“打开文件描述”。

    • 22
  3. Angel
    2019-05-20T03:06:01+08:002019-05-20T03:06:01+08:00

    这取决于您想要达到的目标。由您决定是否可以在与输出相同的文件中出现错误。这只是将文本保存在具有外壳功能的文件中,可让您根据需要进行重定向。没有绝对的“是”或“否”。在 Linux 中,它可以通过多种方式完成,这是我ls notExistingFile existingFile >> output 2>&1 回答问题的方式:就重定向本身而言,是的,它非常安全。

    • 0

相关问题

  • 如何使用 grep 将输出拆分为两个文件?

  • 如何将 airodump-ng 的输出保存到文件中?

  • 从现在开始的某个时间做某事(也许还会在控制台中显示结果)

  • 在后台回显某些内容,但即使您重新启动或停电也能看到它?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve