-1

I really screwed myself over recently. I have a function which will swap the contents of two files:

function swap()         
{
    local TMPFILE=tmp.$$
    mv "$1" "$TMPFILE"
    mv "$2" "$1"
    mv "$TMPFILE""$2"
}               ^

As you can see right near where the carrot is pointing a space is missing. As a result running the following command:

$ swap important.txt not-important.txt

causes important.txt to be overwritten by not-important.txt and important.txt is sent to the abyss of the local bash variable/file

Are there any options short of scraping the raw data on the disk?

$ grep -a -A1000 -B1000 "some text from important.txt" /dev/disk0
4

1 回答 1

2

这个问题毫无意义:Bash 不会自动删除文件,因为它是使用局部变量完成的。该变量实际上只是一个包含文件名的字符串——它不是任何有意义的文件句柄。(Bash确实支持真正的文件句柄,通过使用重定向来打开文件并跟踪相关的 FD 或文件描述符,但您的代码在此没有任何作用)。


也就是说:

mv "$1" "$TEMPFILE"

将您的文件重命名为已存储在 TEMPFILE 变量中的名称。您知道该名称是什么,因为您在之前的行中分配了它:

local TMPFILE=tmp.$$

$$是当前 shell 的 PID(或进程 ID)...所以mv "$1" "$TEMPFILE"也可以写成mv "$1" "tmp.$$". 文件内容不存储在局部变量中;只有文件的名称存储在那里。Bash 不会删除该文件本身——尽管如果您在同一目录中从具有相同 ID 的进程中再次调用该函数,它将选择相同的临时文件名,从而覆盖该文件的先前内容。


因此:在您的函数的情况下swap,它将在磁盘上留下文件,其名称为tmp.###,其中###是运行脚本的 bash 实例的 PID。如果您的内容仍然存在,它们将位于名称与该表单匹配的文件中。

于 2014-09-29T00:50:10.797 回答