您能在脚本运行时编辑它并使更改影响正在运行的脚本吗?
我对一个csh脚本有兴趣,该脚本批量运行多种构建模式,并在整夜运行。如果我想到了什么,我希望能够添加其他命令或注释掉未执行的命令。
如果不可能,请问是否有任何shell或批处理机制可以让我这样做?
当然,我已经尝试过了,但是在几个小时后才能看到它是否有效,而我对幕后发生的事情很好奇。
您能在脚本运行时编辑它并使更改影响正在运行的脚本吗?
我对一个csh脚本有兴趣,该脚本批量运行多种构建模式,并在整夜运行。如果我想到了什么,我希望能够添加其他命令或注释掉未执行的命令。
如果不可能,请问是否有任何shell或批处理机制可以让我这样做?
当然,我已经尝试过了,但是在几个小时后才能看到它是否有效,而我对幕后发生的事情很好奇。
至少在我的环境中,它确实会影响 bash,而且是以非常不愉快的方式。请看以下代码。首先是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.
(当然自动化处理远比这个示例更好,但上述示例易于阅读。)
[编辑] 这是不可预测的,因此存在危险。 最佳解决方法是,如此描述把所有内容都放在括号里,在结束括号之前,加上"exit"。 仔细阅读链接的答案以避免陷阱。
[添加] 精确的行为取决于额外的换行符,也可能取决于您的Unix版本、文件系统等。如果您只想查看一些影响,请在“read”行之前和/或之后在b.sh中添加“echo foo/bar”。
b.sh
。dave4220和我回答的要点是这种影响很难预测。(顺便说一下,“affection”这个名词的意思是“爱”=) - teika kazura试试这个...创建一个名为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 $?
}
花括号保护免于编辑,exit命令保护免于追加。当然,如果bash带有一个选项,比如-w
(整个文件),或者其他可以达到这个效果的东西,那么我们所有人都会更好。
bashx
肯定可以解决问题,但像 {...}; exit $?
这样的解决方案可能存在竞争条件,即文件在代码(安全的部分)和退出命令(不安全的部分)之间被编辑。我认为你必须将退出命令放在花括号中以确保安全。 - Erik Aronesty将你的脚本分成函数,并每次调用一个函数时从单独的文件中source
它。然后,您可以随时编辑文件,运行中的脚本在下一次获取源时会捕捉到这些更改。
foo() {
source foo.sh
}
foo
好问题!希望这个简单的脚本能够帮到您。
#!/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文件进行的更改将由执行脚本来实施!
#!/usr/bin/env python3
import time
print('Starts')
time.sleep(10)
print('Finishes unchanged')
然后在另一个 shell 中,在此期间保持休眠状态,编辑最后一行。当此操作完成时,它会显示未更改的行,可能是因为正在运行一个 .pyc
文件?在 Ubuntu 和 macOS 上都发生了同样的情况。
我没有安装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
嗯。
我猜对shell脚本的编辑只有在重新运行后才会生效。
Change didn'ned
。 - Kirill Bulygin我听到了...但是如果加上一些间接引用呢:
BatchRunner.sh
Command1.sh
Command2.sh
Command1.sh
runSomething
Command2.sh
runSomethingElse
那么在BatchRunner运行之前,您应该能够编辑每个命令文件的内容,对吗?
或者
更清晰的版本将使BatchRunner查找一个单一的文件,在其中逐行连续运行。然后,您应该能够在第一个文件正在运行时编辑这个第二个文件,对吗?
使用Zsh代替进行脚本编写。
据我所知,Zsh不会表现出这种令人沮丧的行为。