我在bash脚本中有一个while循环:
示例:
while read LINE
do
echo $LINE >> $log_file
done < ./sample_file
我的问题是为什么当我在脚本运行时删除sample_file时,循环没有结束,我看到log_file正在更新?没有输入时循环如何继续?
答案 0 :(得分:2)
在unix中,文件不会被删除,直到它的最后一个目录条目被删除(例如,使用rm
)和它的最后一个打开文件句柄被关闭。有关详细信息,请参阅this question(特别是MarkR&#39;答案)。在脚本的情况下,文件作为while read
循环的stdin打开,并且直到该循环退出(或关闭其stdin),rm
该文件实际上不会将其从磁盘上删除。
如果你愿意,你可以很容易地看到这种效果。打开三个终端窗口。在第一个中,运行命令cat >/tmp/deleteme
。在第二个中,运行tail -f /tmp/deleteme
。第三,运行其他两个命令后,运行rm /tmp/deleteme
。此时,文件已取消链接,但cat
和tail
进程都有打开的文件句柄,因此它实际上没有被删除。您可以通过键入第一个终端窗口(运行cat
)来证明这一点,每次点击返回时,tail
都会看到新行添加到文件中并在第二个窗口中显示。< / p>
在您结束这两个命令之前,文件实际上不会被删除(Control-D将结束cat
,但您需要Control-C来终止tail
)。
答案 1 :(得分:2)
请参阅"Why file is accessible after deleting in unix?",了解您在此处观察到的内容。
简而言之......
潜在的rm以及可能似乎删除文件的任何其他命令 有系统调用取消链接。它被称为取消链接,而不是删除或 deletefile或类似的东西,因为它不会删除文件。它 删除作为关联的链接(a.k.a.目录条目) 在文件和目录中的名称之间。
您可以使用函数truncate
来销毁实际内容(如果您需要更安全,则使用shred
),这会立即停止执行示例循环。
答案 2 :(得分:0)
当时shell执行while循环,已经读取了sample_file
内容,并且在该点之后文件是否存在无关紧要。
测试脚本:
$ cat test.sh
#!/bin/bash
while read line
do
echo $line
sleep 1
done < data_file
测试文件:
$ seq 1 10 > data_file
现在,在一个终端中运行脚本,在另一个终端中,你去删除文件data_file
,你仍会看到脚本打印的1到10个数字。