更新:这是How to make shell scripts robust to source being changed as they run
的转贴这是一件困扰我的小事:
显然,脚本是通过从文件中加载每行所需的来解释的。有没有什么方法可以让脚本向shell指示整个脚本文件应该一次性读入内存?例如,Perl脚本似乎这样做:编辑代码文件不会影响当前正在解释它的进程(因为它最初被解析/编译?)。
我知道有很多方法可以解决这个问题。例如,我可以尝试类似:
cat script.sh | sh
或
sh -c "`cat script.sh`"
...如果脚本文件很大并且流缓冲区和命令行参数的大小有限,那么这些可能无法正常工作。我还可以编写一个辅助包装器,将脚本文件复制到一个锁定的临时文件然后执行它,但这看起来不太便携。
所以我希望最简单的解决方案只涉及对脚本的修改,而不是调用它的方式。我可以在脚本开头添加一行或两行吗?我不知道这样的解决方案是否存在,但我猜它可能会使用$ 0变量......
答案 0 :(得分:8)
我发现的最佳答案是对How to make shell scripts robust to source being changed as they run提供的解决方案的微小变化。感谢camh注意到转贴!
#!/bin/sh
{
# Your stuff goes here
exit
}
这可以确保最初解析所有代码;请注意,“退出”对于确保稍后不访问该文件以查看是否还有其他行要解释至关重要。另外,如前一篇文章所述,这并不能保证脚本调用的其他脚本是安全的。
感谢大家的帮助!
答案 1 :(得分:2)
如何编辑它的解决方案。
如果脚本正在运行,则在编辑之前,请执行以下操作:
mv script script-old
cp script-old script
rm script-old
由于shell保持文件打开,只要你不改变open inode的内容,一切都会正常工作。
以上是有效的,因为mv将保留旧的inode,而cp将创建一个新的inode。由于文件的内容在打开时实际上不会被删除,因此您可以立即将其删除,并在shell关闭文件后将其清除。
答案 2 :(得分:2)
使用不修改现有文件的编辑器,而是创建新文件,然后替换旧文件。例如,在Vim中使用:set writebackup backupcopy=no
答案 3 :(得分:1)
根据bash文档而不是
#!/bin/bash
body of script
你试试
#!/bin/bash
script=$(cat <<'SETVAR'
body of script
SETVAR)
eval "$script"
然后我认为你会出差。
答案 4 :(得分:0)
考虑为快速和肮脏的工作创建一个新的爆炸路径。如果您使用以下命令启动脚本:
#!/usr/local/fastbash
或者其他什么,那么你可以编写一个使用你提到的方法之一的fastbash包装器。为了便于移植,可以创建一个从fastbash到bash的符号链接,或者在脚本中有一条注释说可以用bash替换fastbash。
答案 5 :(得分:0)
如果您使用Emacs,请尝试M-x customize-variable break-hardlink-on-save
。设置此变量将告诉Emacs写入临时文件,然后将temp文件重命名为原始文件,而不是直接编辑原始文件。这应该允许正在运行的实例在保存新版本时保留其未修改的版本。
据推测,其他半智能编辑也会有类似的选择。