为什么文件描述器在 grep 命令后重定向更改?[已结束]

Why the file describer redirected changes after grep command? [closed]

提问人:chen zhang 提问时间:9/24/2023 更新时间:9/24/2023 访问量:154

问:


这个问题似乎不是关于帮助中心定义的范围内的编程。

2个月前关闭。

$exec 3<input.txt
$sleep 60 >&3 &
[1] 32524
$ cd/proc/32534/fd 
$ ls -l
lrwx------. 1 zhangchen zhangchen 64 Sep 24 18:29 0 -> /dev/pts/0
lr-x------. 1 zhangchen zhangchen 64 Sep 24 18:29 1 -> /home/zhangchen/input.txt
lrwx------. 1 zhangchen zhangchen 64 Sep 24 18:29 2 -> /dev/pts/0
lr-x------. 1 zhangchen zhangchen 64 Sep 24 18:29 3 -> /home/zhangchen/input.txt

$grep test_word <&3
test_word
$grep test_word <&3
[nothing output] 

grep 不是使用描述符 1 搜索文件吗,为什么 grep 更改了描述符 3 的文件?

Linux Bash Shell 格雷普

评论

0赞 Charles Duffy 9/24/2023
sleep 60 >&3 &不会改变任何有意义的东西。是 的缩写,这就是为什么您看到 FD 3 被复制到 FD 1 以进行该过程的原因,但这与您的第二个 grep 不起作用的原因没有任何关系。>&31>&3sleep
0赞 Charles Duffy 9/24/2023
(同样,是 的缩写,因此,如果您查看两个 s 的 FD 表,您会看到这些进程的 FD 3 被复制到 FD 0)。<&30<&3grep
0赞 Charles Duffy 9/24/2023
...需要明确的是,grep 从 stdin, FD 0 搜索内容;它不搜索 FD 1 -- 1 是 stdout,它在那里写入其输出。
0赞 Charles Duffy 9/24/2023
...如果你问为什么 FD 3 仍然设置在 之后的睡眠命令上,那是因为你没有做任何事情来取消它; 是从 3 到 1 的副本,而不是从 3 到 1 的移动;但这与 grep 无关。>&3>&3
0赞 Charles Duffy 9/24/2023
(另外,请记住,它正在复制指针,因此 3 和 1 都指向同一个内核对象;这就是为什么在运行后从 FD 0 读取也会更改 FD 3 描述符在文件中的位置,该描述符指向相同的句柄)<&3

答:

0赞 Andrew Richards 9/24/2023 #1

你的问题模棱两可:你提供了一些命令及其输出,然后是一个问题,希望读者理解你的意图;我建议,如果你花更多的时间仔细写你的问题,你会得到更多有用的答案。也就是说,如果我正确理解了您的问题,grep 正在使用文件描述符 3,因为您使用 .<&3

评论

0赞 Charles Duffy 9/24/2023
这并不能解释为什么 grep 只发出一次输出(这显然是 OP 想要询问的)。
2赞 Charles Duffy 9/24/2023 #2

它不会更改 FD 3 上打开的文件,或者该文件的内容是什么。更改的是您在文件中的位置

你只开了一次。input.txt

在运行 grep 之前,文件指针位于文件的前面。

运行 grep 后,文件指针位于文件末尾。

它仍然指向同一个文件,但您不再位于它的前面,因此,如果您正在运行的程序不用于倒回前面,则没有内容可供阅读。seek()


如果您运行的程序可以倒回前面,则可以这样做:

# Define a "rewind" function that uses Python
rewind() {
  python -c 'import os, sys; os.lseek(int(sys.argv[1]), 0, os.SEEK_SET)' "$@"
}

# Create our input file
echo 'test_word' >input.txt

# Redirect from the input file
exec 3<input.txt

# Read from the input file once
grep test_word <&3

# Rewind the input file back to the beginning
rewind 3

# _Now_ we can read from the input file a second time
grep test_word <&3

评论

0赞 chen zhang 9/24/2023
为什么 grep 可以将 FD3 从文件的前面更改到末尾,我认为 grep 使用它的 FD0(stdin) 进行搜索,而不是它的 FD3,也许我弄错了什么?
0赞 chen zhang 9/24/2023
感谢您对我问题的耐心和深思熟虑的回答
0赞 Charles Duffy 9/24/2023
你是对的:当没有提供显式文件名时(或者当它被赋予显式文件名 );但是,在已运行的上下文中,FD 0 是 FD 3 的副本,因此它们指向内核中的相同结构 - 它是存储文件中位置的结构。-<&3