在 shell 脚本运行时编辑它
您可以在 shell 脚本运行时对其进行编辑并使更改影响正在运行的脚本吗?
我很好奇 csh 脚本的具体情况,我让该批处理运行一堆不同的构建风格并运行整夜。如果我在操作过程中发生了一些事情,我想进去添加额外的命令,或者注释掉未执行的命令。
如果不可能,是否有任何外壳或批处理机制可以让我做到这一点?
当然,我已经尝试过了,但要过几个小时才能看到它是否有效,而且我很好奇幕后发生了什么或没有发生什么。
Can you edit a shell script while it's running and have the changes affect the running script?
I'm curious about the specific case of a csh script I have that batch runs a bunch of different build flavors and runs all night. If something occurs to me mid operation, I'd like to go in and add additional commands, or comment out un-executed ones.
If not possible, is there any shell or batch-mechanism that would allow me to do this?
Of course I've tried it, but it will be hours before I see if it worked or not, and I'm curious about what's happening or not happening behind the scenes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
它确实会影响,至少在我的环境中是这样,但是非常不愉快。请参阅这些代码。首先
a.sh
:b.sh
:Do
在我的例子中,输出始终是:(
当然,自动化它要好得多,但上面的示例是可读的。 )
[编辑] 这是不可预测的,因此很危险。 最好的解决方法是,按照此处所述 将所有内容放在大括号中,然后再进行右大括号,输入“exit”。 仔细阅读链接的答案以避免陷入陷阱。
[补充] 确切的行为取决于一个额外的换行符,也许还取决于您的 Unix 风格、文件系统等。如果您只是想查看一些影响,只需在 b.sh 之前和/或之后添加“echo foo/bar”即可“读”行。
It does affect, at least bash in my environment, but in very unpleasant way. See these codes. First
a.sh
:b.sh
:Do
In my case, the output is always:
(Of course it's far better to automate it, but the above example is readable.)
[edit] This is unpredictable, thus dangerous. The best workaround is , as described here put all in a brace, and before the closing brace, put "exit". Read the linked answer well to avoid pitfalls.
[added] The exact behavior depends on one extra newline, and perhaps also on your Unix flavor, filesystem, etc. If you simply want to see some influences, simply add "echo foo/bar" to b.sh before and/or after the "read" line.
试试这个...创建一个名为 bash-is-odd.sh 的文件:
这表明 bash 确实是“随时”解释脚本。事实上,编辑长时间运行的脚本会产生不可预测的结果,插入随机字符等。为什么?因为 bash 从最后一个字节位置读取,所以编辑会移动当前读取的字符的位置。
总之,由于这个“功能”,Bash 非常非常不安全。 svn 和 rsync 与 bash 脚本一起使用时特别麻烦,因为默认情况下它们“合并”结果......就地编辑。 rsync 有一种模式可以解决这个问题。 svn 和 git 没有。
我提出一个解决方案。创建一个名为
/bin/bashx
的文件:现在在脚本上使用
#!/bin/bashx
并始终使用bashx
而不是 <代码>bash。这解决了问题 - 您可以安全地rsync
您的脚本。@AF7 提出/测试的替代(内联)解决方案:
花括号防止编辑,退出防止追加。当然,如果 bash 带有一个选项,例如
-w
(整个文件),或者执行此操作的选项,我们都会好得多。Try this... create a file called
bash-is-odd.sh
:That demonstrates that bash is, indeed, interpreting the script "as you go". Indeed, editing a long-running script has unpredictable results, inserting random characters etc. Why? Because bash reads from the last byte position, so editing shifts the location of the current character being read.
Bash is, in a word, very, very unsafe because of this "feature". svn and
rsync
when used with bash scripts are particularly troubling, because by default they "merge" the results... editing in place.rsync
has a mode that fixes this. svn and git do not.I present a solution. Create a file called
/bin/bashx
:Now use
#!/bin/bashx
on your scripts and always run them withbashx
instead ofbash
. This fixes the issue - you can safelyrsync
your scripts.Alternative (in-line) solution proposed/tested by @AF7:
Curly braces protect against edits, and exit protects against appends. Of course, we'd all be much better off if bash came with an option, like
-w
(whole file), or something that did this.将脚本分解为函数,每次调用函数时,您都可以从单独的文件中
source
它。然后,您可以随时编辑这些文件,并且您的运行脚本将在下次获取时获取更改。Break your script into functions, and each time a function is called you
source
it from a separate file. Then you could edit the files at any time and your running script will pick up the changes next time it gets sourced.好问题!
希望这个简单的脚本有所帮助
在 Linux 下,如果您输入得足够快,对正在执行的 .sh 所做的更改似乎是由正在执行的脚本执行的!
Good question!
Hope this simple script helps
It does seem under linux that changes made to an executing .sh are enacted by the executing script, if you can type fast enough!
一个有趣的旁注 - 如果您正在运行 Python 脚本,它不会改变。 (对于任何了解 shell 如何运行 Python 脚本的人来说,这可能是显而易见的,但我认为这对于寻找此功能的人来说可能是一个有用的提醒。)
我创建了:
然后在另一个 shell 中,当它处于睡眠状态时,编辑最后一行。完成后,它会显示未更改的行,大概是因为它正在运行
.pyc
? Ubuntu 和 macOS 上也会发生同样的情况。An interesting side note - if you are running a Python script it does not change. (This is probably blatantly obvious to anyone who understands how shell runs Python scripts, but thought it might be a useful reminder for someone looking for this functionality.)
I created:
Then in another shell, while this is sleeping, edit the last line. When this completes it displays the unaltered line, presumably because it is running a
.pyc
? Same happens on Ubuntu and macOS.我没有安装 csh,但
运行它,快速编辑最后一行以读取
输出为
Hrmph。
我想对 shell 脚本的编辑只有在重新运行后才会生效。
I don't have csh installed, but
Run that, quickly edit the last line to read
Output is
Hrmph.
I guess edits to the shell scripts don't take effect until they're rerun.
如果这一切都在一个脚本中,那么不,它不会工作。但是,如果您将其设置为调用子脚本的驱动程序脚本,那么您可能能够在调用子脚本之前更改子脚本,或者如果您正在循环,则在再次调用子脚本之前更改子脚本,在这种情况下,我相信这些更改都会体现在执行中。
If this is all in a single script, then no it will not work. However, if you set it up as a driver script calling sub-scripts, then you might be able to change a sub-script before it's called, or before it's called again if you're looping, and in that case I believe those changes would be reflected in the execution.
我没有听到...但是如果有一些间接的:
BatchRunner.sh
Command1.sh
Command2.sh
那么你应该能够在 BatchRunner 到达之前编辑每个命令文件的内容,对吗?
或
更简洁的版本会让 BatchRunner 查看单个文件,在该文件中一次连续运行一行。那么您应该能够在第一个文件运行时编辑第二个文件,对吧?
I'm hearing no... but what about with some indirection:
BatchRunner.sh
Command1.sh
Command2.sh
Then you should be able to edit the contents of each command file before BatchRunner gets to it right?
OR
A cleaner version would have BatchRunner look to a single file where it would consecutively run one line at a time. Then you should be able to edit this second file while the first is running right?
使用 Zsh 代替您的脚本。
据我所知,Zsh 不会表现出这种令人沮丧的行为。
Use Zsh instead for your scripting.
AFAICT, Zsh does not exhibit this frustrating behavior.
通常,在脚本运行时对其进行编辑的情况并不常见。您所要做的就是对您的操作进行控制检查。使用 if/else 语句检查条件。如果某件事失败了,就这样做,否则就那样做。这就是要走的路。
usually, it uncommon to edit your script while its running. All you have to do is to put in control check for your operations. Use if/else statements to check for conditions. If something fail, then do this, else do that. That's the way to go.
脚本不是这样工作的;执行副本独立于您正在编辑的源文件。下次运行脚本时,它将基于最近保存的源文件版本。
将此脚本分解为多个文件并单独运行它们可能是明智的做法。这将减少执行失败的时间。 (即,将批次拆分为一个构建风味脚本,单独运行每个脚本以查看哪个脚本造成了问题)。
Scripts don't work that way; the executing copy is independent from the source file that you are editing. Next time the script is run, it will be based on the most recently saved version of the source file.
It might be wise to break out this script into multiple files, and run them individually. This will reduce the execution time to failure. (ie, split the batch into one build flavor scripts, running each one individually to see which one is causing the trouble).