吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 691|回复: 10
收起左侧

[求助] 为什么 cat < w1 > w1会清空 W1

[复制链接]
qy711 发表于 2023-10-8 16:49

在Linux环境下,w1内有内容,当输入cat < w1 > w1 时,w1内容会清空,请问是什么原理,哪位大牛帮解释下???

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
ManaCola + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

hrh123 发表于 2023-10-8 17:33
本帖最后由 hrh123 于 2023-10-8 17:58 编辑

没记错的话好像是先处理>


编辑

貌似记错了,好像是同时运行还是咋的,机制我也不知道,man page上也没翻到,等大佬吧

周易 发表于 2023-10-8 22:52
本帖最后由 周易 于 2023-10-8 22:53 编辑

以下以Bash为例,我们假定文件名为w1。需要注意的是,不同Shell可能有不同的实现方式。

Redirections are processed in the order they appear, from left to right.

因此不是优先级问题。

我们首先明确一点:重定向是怎么实现的。

实现输入重定向(STDIN_FILENO = 0)的伪代码如下。

fd = openat(AT_FDCWD, "w1", O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);

实现输出重定向(STDOUT_FILENO = 1)的伪代码如下。

fd = openat(AT_FDCWD, "w1", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, STDOUT_FILENO);
close(fd);

这些都是在执行cat之前依次发生的。

对于以下两种方式:

  • cat < w1 > w1
  • cat > w1 < w1

区别只在于执行伪代码两者的顺序不同。

不难发现,如果指定了输出重定向,则在打开文件过程中w1的内容将会被清空。

O_TRUNC

If the file already exists and is a regular file and the access mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0.

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
qy711 + 1 + 1 谢谢@Thanks!
hrh123 + 1 + 1 我很赞同!

查看全部评分

Seven_2017 发表于 2023-10-8 23:07
有点厉害哦,我只知道重定向空到文件w1所以清空了
爱飞的猫 发表于 2023-10-8 23:11

因为是同时打开的。一个是打开只读 < w1,一个是打开时就清空文件 > w1

如果你真的需要达到你想要的效果,你应当使用 sponge 指令:

cat w1 | sponge w1

注意他也没用 > 符号(如果真用了就直接清空了)。原理则是将管道传输进来的数据全部放到内存,然后等 stdin 结束写入后再打开文件写出。


免费评分

参与人数 2吾爱币 +2 热心值 +1 收起 理由
hrh123 + 1 + 1 热心回复!
周易 + 1 我很赞同!实际上是从左到右打开复制关闭,并不同时。

查看全部评分

 楼主| qy711 发表于 2023-10-8 23:30
爱飞的猫 发表于 2023-10-8 23:11
[md]因为是同时打开的。一个是打开只读 `< w1`,一个是打开时就清空文件 `> w1`。

如果你真的需要达到你 ...

请问"一个是打开时就清空文件 `> w1`" 这打开的是W1 还是不存在的空值?

点评

w1 不是你 1L 描述里用的文件名吗… 另外建议你看 @周易 在上面的答案,是根据源码分析的: https://www.52pojie.cn/forum.php?mod=redirect&goto=findpost&ptid=1841941&pid=48188419  详情 回复 发表于 2023-10-8 23:33
爱飞的猫 发表于 2023-10-8 23:33
qy711 发表于 2023-10-8 23:30
请问"一个是打开时就清空文件 `> w1`" 这打开的是W1 还是不存在的空值?

w1 不是你 1L 描述里用的文件名吗…

另外建议你看 @周易 在上面的答案,是根据源码分析的:

https://www.52pojie.cn/forum.php ... 41&pid=48188419
hrh123 发表于 2023-10-9 20:42
爱飞的猫 发表于 2023-10-8 23:33
w1 不是你 1L 描述里用的文件名吗…

另外建议你看 @周易 在上面的答案,是根据源码分析的:

我想知道这个<>是bash内建的还是cat自带的

点评

Shell 实现的。如果你使用的是 Bash 作为 Shell 解释器,那就是 Bash。  详情 回复 发表于 2023-10-9 20:53
爱飞的猫 发表于 2023-10-9 20:53
hrh123 发表于 2023-10-9 20:42
我想知道这个是bash内建的还是cat自带的

Shell 实现的。如果你使用的是 Bash 作为 Shell 解释器,那就是 Bash。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
hrh123 + 1 + 1 懂了懂了

查看全部评分

hrh123 发表于 2023-10-14 20:23
爱飞的猫 发表于 2023-10-9 20:53
Shell 实现的。如果你使用的是 Bash 作为 Shell 解释器,那就是 Bash。

所以问题就在于shell在执行cat读取数据前先处理了重定向,打开并O_TRUNC了文件,我的理解没问题吧

点评

和我之前说的一样,细节方面我不清楚,你应该参考 @周易 的答案,他带着源码分析的。  详情 回复 发表于 2023-10-14 23:36
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 13:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表