在shell脚本运行时编辑它

时间:2010-08-03 15:49:52

标签: linux shell csh

您可以在shell脚本运行时编辑它并让更改影响正在运行的脚本吗?

我很好奇csh脚本的具体情况我有批处理运行一堆不同的构建风格并且整夜运行。如果我在操作中遇到某些问题,我想进入并添加其他命令,或者注释掉未执行的命令。

如果不可能,是否有允许我这样做的shell或批处理机制?

当然我已经尝试过了,但是在我看到它是否有效之前还需要几个小时,而且我很好奇幕后发生或未发生的事情。

11 个答案:

答案 0 :(得分:41)

[edit]另请参阅this answer, section 3了解变通方法。

确实影响,至少在我的环境中受到影响,但是以非常不愉快的方式。请参阅这些代码。首先a.sh

#!/bin/sh

echo "First echo"
read y

echo "$y"

echo "That's all."

b.sh

#!/bin/sh

echo "First echo"
read y

echo "Inserted"

echo "$y"

# echo "That's all."

待办事项

$ cp a.sh run.sh
$ ./run.sh
$ # open another terminal
$ cp b.sh run.sh  # while 'read' is in effect
$ # Then type "hello."

就我而言,输出总是:

hello
hello
That's all.
That's all.

这是不可预测的,因此很危险。有关解决方法,请参阅this answer, section 3

[已添加]确切的行为取决于一个额外的换行符,也可能取决于你的Unix风格,文件系统等。如果你只是想看到一些影响,只需在之前添加“echo foo / bar”到b.sh /或在“阅读”行之后。

答案 1 :(得分:32)

试试这个......创建一个名为“bash-is-odd.sh”的文件:

#!/bin/bash
echo "echo yes i do odd things" >> bash-is-odd.sh

这表明bash确实是在“你去的时候”解释脚本。实际上,编辑长时间运行的脚本会产生不可预测的结果,插入随机字符等等。为什么?因为bash从最后一个字节位置读取,所以编辑会移动当前正在读取的字符的位置。

总而言之,由于这个“功能”,Bash非常非常不安全。与bash脚本一起使用时,svn和rsync特别令人不安,因为默认情况下它们会“合并”结果......编辑到位。 rsync有一个修复此问题的模式。 svn和git没有。

我提出了一个解决方案。创建一个名为“/ bin / bashx”的文件:

#!/bin/bash
source "$1"

现在在脚本上使用#!/ bin / bashx并始终使用“bashx”而不是bash运行它们。这解决了这个问题 - 你可以安全地rsync你的脚本。

@ AF7提出/测试的替代(在线)解决方案:

{
   # your script
} 
exit $?

大括号可防止编辑,退出可防止附加。当然,如果bash附带一个选项,比如'-w'(整个文件),或者做了这样的事情,我们都会好得多。

答案 2 :(得分:16)

将脚本分解为函数,每次从一个单独的文件中调用一个函数source。然后,您可以随时编辑文件,并且您的运行脚本将在下次获取更改时获取更改。

foo() {
  source foo.sh
}
foo

答案 3 :(得分:2)

好问题! 希望这个简单的脚本有帮助

#!/bin/sh
echo "Waiting..."
echo "echo \"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution\"  " >> ${0}
sleep 5
echo "When I was run, this was the last line"

在Linux下,如果您键入得足够快,似乎正在执行的脚本会对执行中的.sh进行更改!

答案 4 :(得分:1)

我没有安装csh,但是

#!/bin/sh
echo Waiting...
sleep 60
echo Change didn't happen

运行它,快速编辑最后一行以阅读

echo Change happened

输出

Waiting...
/home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string

Hrmph。

我猜对shell脚本的编辑在重新运行之前不会生效。

答案 5 :(得分:1)

如果这只是一个脚本,那么它就不会起作用。但是,如果将其设置为调用子脚本的驱动程序脚本,那么您可以在调用之前更改子脚本,或者在循环之前再次调用子脚本,在这种情况下我相信这些更改将反映在执行中。

答案 6 :(得分:1)

一个有趣的旁注-如果您正在运行Python脚本,则它不会更改。 (这对于任何了解shell如何运行Python脚本的人来说都是显而易见的,但是认为这对于寻找该功能的人可能是一个有用的提醒。)

我创建了:

#!/usr/bin/env python3
import time
print('Starts')
time.sleep(10)
print('Finishes unchanged')

然后在另一个正在休眠的外壳程序中,编辑最后一行。完成此操作后,它会显示未更改的行,可能是因为它正在运行.pyc?在Ubuntu和macOS上也是如此。

答案 7 :(得分:0)

我听不到......但是有一些间接的东西:

BatchRunner.sh

Command1.sh
Command2.sh

Command1.sh

runSomething

Command2.sh

runSomethingElse

那么你应该能够在BatchRunner到达它之前编辑每个命令文件的内容吗?

更干净的版本会让BatchRunner查看单个文件,它会一次连续运行一行。那么你应该能够编辑第二个文件,而第一个文件正在运行吗?

答案 8 :(得分:0)

使用Zsh代替脚本。

AFAICT,Zsh没有表现出这种令人沮丧的行为。

答案 9 :(得分:-5)

通常,在运行时编辑脚本并不常见。您所要做的就是对您的操作进行控制检查。使用if / else语句检查条件。如果出现问题,那么就这样做,否则就这样做。这是要走的路。

答案 10 :(得分:-52)

脚本无法正常工作;执行副本独立于您正在编辑的源文件。下次运行脚本时,它将基于最近保存的源文件版本。

将此脚本分解为多个文件并单独运行可能是明智之举。这将减少执行失败的时间。 (即,将批处理拆分为一个构建样式脚本,单独运行每个脚本以查看哪一个导致问题)。