我可以在运行时修改bash脚本(.sh)文件吗?


28

假设我有一个脚本script.sh,需要一些时间来执行。我执行它./script.sh。当它在终端窗口中运行时,我修改了文件script.sh。这对已经运行的进程有影响吗?

修改后,我执行修改后的文件,因此我现在有两个运行过程。这个可以吗?


Answers:


36

当您对脚本进行更改时,将在磁盘(硬盘-永久存储)上进行更改;当您执行脚本时,脚本将被加载到您的内存(RAM)中。

因此,您对脚本所做的更改不会影响正在运行的脚本,它将运行您执行这些更改之前执行的版本。

但是,当您再次执行更改的脚本而不终止先前正在运行的实例时,该脚本将有两个实例-一个具有更改的实例和一个旧的实例。

警告该脚本使用和修改的资源将发生冲突。例如,如果您正在使用脚本修改文件,则稍后运行的脚本将无法打开该文件进行写入,并且无法正确执行。

更新: 感谢注册用户向我指出了Unix.stackexchange.com上的一个更好的答案。

根据脚本的大小以及所讨论的编译器/解释器的不同,脚本会部分/完全加载。因此,如果未完全加载脚本,则将脚本的一部分加载到内存后,对脚本所做的更改将反映在正在运行的实例上。

因此,建议不要在当前正在运行的磁盘上更改脚本以获取不可预测的输出:首先停止正在运行的实例,然后修改脚本,然后重新执行脚本。


11
并非完美的答案,请阅读unix.stackexchange.com/q/121013/55673
注册用户

@registereduser:哦,是的,这个问题使我想起了我的操作系统课程。只要将我的手放在桌面上(现在就在手机上)
即可

我想对于短脚本来说应该没有问题。
becko 2014年

1
当我使用bash v3.2.48(请参见此处)进行尝试时,它没有缓冲到行尾(并且在执行脚本时修改脚本时严重失败)。我刚刚使用bash v4.3.0重新测试,它缓冲了整个(简短)脚本。所以...我不会指望任何特定的行为。
Gordon Davisson 2014年

1
@RegisteredUser不适用于所有版本的bash-请参阅我链接的示例。
戈登·戴维森

4

我将添加我认为其他答案中未提及的内容。在很大程度上取决于您如何编辑文件。这样做echo "stuff" >file从壳(另一个实例)确实将覆盖该文件,我想。但是,如果您使用例如编辑文件emacs然后保存,则不会发生这种情况。而是在这里,编辑器将旧文件重命名为某个备份名称(也许实际上是删除了先前的备份),然后使用旧名称(现已释放)将其修改后的缓冲区内容写为文件。由于读取脚本的外壳程序(或其他解释程序)几乎肯定只能打开一次文件,因此此后与文件的下落无关,它只是继续读取打开时与文件名关联的物理磁盘文件(由inode编号标识)。因此,即使它以块的形式读取脚本(如果使用缓冲文本I / O,这将是最简单的解决方案),它将继续从文件的旧实例中读取行,这在您的编辑中可能不会更改。


+1我正在使用Sublime Text作为编辑器。您知道它是否也重命名文件emacs吗?
becko 2014年

1
我认为大多数编辑器都将使用重命名方案(即使他们不保留备份版本)也可以避免以下风险:如果在写入过程中发生崩溃,则根本不会保留完整版本的文本。您可以使用“ ls -i”(显示inode号)检查编辑器的行为。
Marc van Leeuwen 2014年

1

这需要更新,以上答案现在仅部分正确:

对于当前版本的bash,在磁盘上运行脚本时对其进行修改会导致bash“尝试”将更改加载到内存中,并将这些更改包含在正在运行的脚本中。如果您的更改在当前执行的行之后,则将加载并执行新的行。但是,这是bash的猜测,可能会正确或错误。

更好的方法是按以下顺序进行操作:1)将脚本加载到内存中2)从磁盘删除脚本3)首先删除磁盘版本将新脚本写入磁盘,内存版本会失去与其的链接因此,当您在第3步中提供新版本时,bash不会尝试将新内容加载到内存版本中。


0

@jobin的答案通常是正确的,但我将添加一些其他答案,具体取决于您想做什么。

如果您想更改脚本,并且想知道它是安全的,那么您想写入一个新文件,而不是现有文件,但是新文件可以位于旧文件所在的位置。将新版本写入新文件,然后用于mv将其移到旧文件的顶部。被替换的文件仍然存在,只是没有从目录链接。您正在运行的脚本可以继续使用它,并且当该脚本关闭其文件句柄时,系统知道它可以安全地清除文件(无论是立即清除还是以后清除)。

如果要动态地执行脚本的行为,则会遇到更困难的问题。我希望您需要将其构建到脚本代码中。Bash脚本可以处理信号(例如,可以捕获kill -USR1 [pid]),然后脚本可以通过重新加载一些代码来做出响应。因此,也许您可​​以获得接近所需功能的功能,但是却不知道所追求的是什么,我看不出这样做的充分理由,而且我怀疑您是否想做这种复杂的事情,您可能想要更复杂的东西编程语言来实现。

如果您想破解没有考虑到这一点而编写的运行脚本的行为,那么您就不走运了。我会毫不犹豫地说任何编程任务都是不可能的,但是如果您有足够的资源和技能来执行此类任务,那么大概就不会在这里问了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.