【发布时间】:2012-01-10 06:25:18
【问题描述】:
Bash 可以给unexpected results if one edits a script while the script is running。但是,能够编辑我在 shell 中运行的脚本的临时副本通常非常方便,但在再次运行之前确保它回到原始位置。有人对 Emacs 的工作流程或自定义有什么建议吗?
【问题讨论】:
Bash 可以给unexpected results if one edits a script while the script is running。但是,能够编辑我在 shell 中运行的脚本的临时副本通常非常方便,但在再次运行之前确保它回到原始位置。有人对 Emacs 的工作流程或自定义有什么建议吗?
【问题讨论】:
我已经有了重命名当前缓冲区文件的功能。是对一个函数的短暂跳转,它可以轻松切换到文件的临时版本,然后再返回。基本上,如果您在访问普通文件“foo.txt”时运行此函数,它将将该文件复制到同一目录中名为“tmp.foo.txt”的新文件中。根据需要进行编辑。当准备好切换回来时,再次运行该函数,它将把临时文件移回原始文件。我使用了前缀“tmp”。而不是后缀,因为 emacs 中的大多数模式识别都是基于后缀的(您可能会做一些更有趣的事情来记住所有缓冲区模式并重新应用......)。
(defun toggle-temp-file ()
(interactive)
(let* ((cur-buf (current-buffer))
(cur-file (buffer-file-name cur-buf))
(cur-file-dir (file-name-directory cur-file))
(cur-file-name (file-name-nondirectory cur-file))
new-file)
(if (string-match "^tmp\\.\\(.+\\)\\'" cur-file-name)
;; temp file -> orig file
(progn
(setq new-file
(concat cur-file-dir (match-string 1 cur-file-name)))
(rename-file cur-file new-file t))
;; orig file -> temp file
(setq new-file (concat cur-file-dir "tmp." cur-file-name))
(copy-file cur-file new-file nil nil t))
(kill-buffer cur-buf)
(find-file new-file)))
【讨论】:
M-x delete-file,按down插入获取正在编辑的文件的路径,按RET删除文件。当您下次保存缓冲区时,这将创建一个新文件。 Bash 将继续执行旧的、已删除的文件。
顺便说一句,在大多数情况下,您甚至不需要采取这种预防措施。 Emacs 通常会保存到一个临时文件,然后将该临时文件重命名为正确的文件名(这会删除旧文件,除非它被保存为备份)。只有当 Emacs 检测到它不能正确地重新创建文件时,Emacs 才会覆盖原地文件:如果文件有硬链接,或者如果您对目录没有写权限。 (我简化了一点;详细信息在files.el 中的basic-save-buffer-2 函数中。)只要文件有一个目录条目并且您对包含脚本的目录具有写权限,只需按C-x C-s .
【讨论】:
file-precious-flag 默认为 nil(但如果启用,可能会破坏硬链接)。仅当break-hardlink-on-save 不是nil(默认情况下不是)时才考虑数量 的硬链接。我没有看到任何意味着“永远不要破坏硬链接,但如果可能的话,写临时文件和重命名”的配置......
backup-by-copying 设置 (nil) 得到缓解,因为 Emacs 会将原始文件重命名为备份,然后为原始文件名创建一个新文件;但是,这仅适用于实际发生备份的情况。
[edit] best workaround 是在 shell 脚本端完成的,不是 在 Emacs 中。简而言之,_put all 在一个大括号中,并在右大括号之前放置“exit”。 仔细阅读链接的答案以避免陷阱。
在这个回复中,我用理论补充了 Gilles 的回答。
删除安全但修改不安全的原因是,在 Unix 中,已删除的文件无法从文件系统访问,但打开文件的进程(此处为 /bin/bash)仍然可以读取它,如解释here。这并不是说 bash 做了什么特别的事情,比如缓冲整个文件,但它只是读取。 (即使删除后,您也可以在脚本运行时恢复它,as explained here。在 bash 中,脚本似乎总是以 255 打开,/proc/<pid>/fd/255。)
[编辑] 根据 OP 的要求,我的 old answer 包括 Emacs 解决方案和合作伙伴。但是经过多年的经验,我确信上面的指针是最好的,比任何其他尝试都好得多。)
【讨论】:
只需将此解决方案添加为保护正在运行的 BASH 脚本不被更改的简单而干净的方法:
#! /bin/bash
{
your_code;
exit;
}
【讨论】: