在运行时编辑shell脚本
你可以在运行的时候编辑一个shell脚本,并且这些改变会影响正在运行的脚本吗?
我对csh脚本的具体情况感到好奇,我有批处理运行一堆不同的构build口味,并运行一整夜。 如果中间操作发生,我想进去添加额外的命令,或者注释掉未执行的命令。
如果不可能的话,是否有任何shell或批处理机制可以让我这样做?
当然,我已经尝试过了,但是在我看到它是否有效之前还需要几个小时,而且我很好奇在幕后发生了什么或者没有发生什么。
脚本不这样工作; 正在执行的副本与正在编辑的源文件无关。 下次脚本运行时,它将基于最近保存的源文件版本。
将这个脚本分解成多个文件并逐个运行它可能是明智的。 这将减less执行时间到失败。 (即,将批处理分成一个构build风格脚本,分别运行每个脚本以查看哪个脚本导致故障)。
另请参阅此答案,第3部分了解变通方法。
这确实影响到,至less是在我的环境中,但以非常不愉快的方式 。 看到这些代码。 首先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."
在我的情况下,输出总是:
你好 你好 就这样。 就这样。
这是不可预测的,因此是危险的。 看到这个答案,第3部分的解决方法。
[增加]确切的行为取决于一个额外的换行符,也许还在你的Unix风格,文件系统等。如果你只是想看到一些影响,只需在b.sh之前和/或之后添加“echo foo / bar” “读”一行。
试试这个…创build一个名为“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不。
我提出一个解决scheme。 创build一个名为“/ bin / bashx”的文件:
#!/bin/bash source "$1"
现在在你的脚本中使用#!/ bin / bashx,并且总是用“bashx”而不是bash来运行它们。 这解决了这个问题 – 你可以安全地rsync你的脚本。
@ AF7提出/testing的替代(在线)解决scheme:
{ # your script } exit $?
花括号防止编辑,并退出防止追加。 当然,如果bash带有一个选项,比如'-w'(整个文件),或者做了这些,我们都会好得多。
把你的脚本分解成函数,每次函数被调用时,你source
从一个单独的文件中获取它。 然后,您可以随时编辑这些文件,而且您的运行脚本将在下一次获取源代码时收集这些更改。
foo() { source foo.sh } foo
我没有安装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脚本不会生效,直到他们重新运行。
我不知道…但是有些间接的事情呢?
BatchRunner.sh
Command1.sh Command2.sh
Command1.sh
runSomething
Command2.sh
runSomethingElse
那么你应该能够编辑每个命令文件的内容之前BatchRunner得到它的权利?
要么
一个更清洁的版本可以使BatchRunner查找单个文件,并且每次连续运行一行。 那么你应该能够编辑第二个文件,而第一个正在运行的权利?
如果这是全部在一个脚本中,那么它不会工作。 但是,如果将其设置为调用子脚本的驱动程序脚本,则可能可以在调用子脚本之前或在循环之前再次调用子脚本,在这种情况下,我相信这些更改将体现在执行中。
通常,在运行时编辑脚本的情况并不常见。 所有你需要做的就是控制检查你的操作。 使用if / else语句来检查条件。 如果失败了,那就这样做,否则就这样做。 这是要走的路。