您可以在shell脚本运行时编辑它并让更改影响正在运行的脚本吗?
我很好奇csh脚本的具体情况我有批处理运行一堆不同的构建风格并且整夜运行。如果我在操作中遇到某些问题,我想进入并添加其他命令,或者注释掉未执行的命令。
如果不可能,是否有允许我这样做的shell或批处理机制?
当然我已经尝试过了,但是在我看到它是否有效之前还需要几个小时,而且我很好奇幕后发生或未发生的事情。
答案 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)
脚本无法正常工作;执行副本独立于您正在编辑的源文件。下次运行脚本时,它将基于最近保存的源文件版本。
将此脚本分解为多个文件并单独运行可能是明智之举。这将减少执行失败的时间。 (即,将批处理拆分为一个构建样式脚本,单独运行每个脚本以查看哪一个导致问题)。