bash 试运行一个有潜在危险的脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22952959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dry-run a potentially dangerous script?
提问by James Elegan
A predecessor of mine installed a crappy piece of software on an old machine (running Linux) which I've inherited. Said crappy piece of software installed flotsam all over the place, and also is sufficiently bloated that I want it off ASAP -- it no longer has any functional purpose since we've moved on to better software.
我的前任在我继承的旧机器(运行 Linux)上安装了一个蹩脚的软件。那个蹩脚的软件到处都是,而且还很臃肿,我想尽快把它关掉——因为我们已经转向更好的软件,它不再有任何功能用途。
Vendor provided an uninstall script. Not trusting the crappy piece of software, I opened the uninstall script in an editor (a 200+ line Bash monster), and it starts off something like this:
供应商提供了卸载脚本。不相信这个糟糕的软件,我在编辑器(一个 200 多行的 Bash 怪物)中打开了卸载脚本,它开始是这样的:
SWROOT=`cat /etc/vendor/path.conf`
...
rm -rf $SWROOT/bin
...
It turns out that /etc/vendor/path.conf
is missing. Don't know why, don't know how, but it is. If I had run this lovely little script, it would have deleted the /bin
folder, which would have had rather amusing implications. Of course this script required root
to run!
事实证明这/etc/vendor/path.conf
是缺失的。不知道为什么,不知道如何,但它是。如果我运行这个可爱的小脚本,它会删除/bin
文件夹,这会产生相当有趣的影响。当然这个脚本需要root
运行!
I've dealt with this issue by just manually running all the install commands (guh) where sensible. This kind of sucked because I had to interpolate all the commands manually. In general, is there some sort of way I can "dry run" a script to have it dump out all the commands it wouldexecute, without it actually executing them?
我已经通过在合理的情况下手动运行所有安装命令 (guh) 来解决这个问题。这很糟糕,因为我必须手动插入所有命令。一般来说,是否有某种方法可以“试运行”一个脚本,让它转储它会执行的所有命令,而不实际执行它们?
回答by David W.
You could try running the script under Kornshell. When you execute a script with ksh -D
, it reads the commands and checks them for syntax, but doesn't execute them. Combine that with set -xv
, and you'll print out the commands that will be executed.
您可以尝试在 Kornshell 下运行该脚本。当您使用 执行脚本时ksh -D
,它会读取命令并检查它们的语法,但不会执行它们。将其与 结合,set -xv
您将打印出将要执行的命令。
You can also use set -n
for the same effect. Kornshell and BASH are fairly compatible with each other. If it's a pure Bourne shell script, both Kornshell and BASH will execute it pretty much the same.
您也可以使用set -n
相同的效果。Kornshell 和 BASH 彼此相当兼容。如果它是一个纯粹的 Bourne shell 脚本,那么 Kornshell 和 BASH 将几乎相同地执行它。
You can also run ksh -u
which will cause unset shell variables to cause the script to fail. However, that wouldn't have caught the catless cat of a nonexistent file. In that case, the shell variable was set. It was set to null.
您还可以运行ksh -u
这将导致未设置的 shell 变量导致脚本失败。但是,这不会抓住不存在文件的无猫猫。在这种情况下,设置了 shell 变量。它被设置为空。
Of course, you could run the script under a restricted shell too, but that's probably not going to uninstall the package.
当然,您也可以在受限制的 shell 下运行脚本,但这可能不会卸载软件包。
That's the best you can probably do.
这可能是你能做的最好的事情。
回答by mklement0
bash
does notoffer dry-run functionality(and neither do ksh
, zsh
, or any other shell I know).
bash
并没有提供干式运行的功能(也不做ksh
,zsh
或任何其他的shell我知道)。
It seems to me that offering such a feature in a shell would be next to impossible: state changes would have to be simulatedand any command invoked - whether built in or external - would have to be aware of these simulations.
在我看来,在 shell中提供这样的功能几乎是不可能的:必须模拟状态更改,并且调用的任何命令 - 无论是内置的还是外部的 - 都必须了解这些模拟。
The closest thing that bash
, ksh
, and zsh
offer is the ability to syntax-checka scriptwithout executing it, via option -n
:
bash
, ksh
, 和zsh
提供的最接近的东西是无需执行脚本即可通过选项进行语法检查的能力:-n
bash -n someScript # syntax-check a script, without executing it.
- If there are no syntax errors, there will be no output, and the exit code will be 0.
- If there are syntax errors, analysis will stop at the firsterror, an error message including the line number is written to stderr, and the exit code will be:
2
inbash
3
inksh
1
inzsh
- 如果没有语法错误,则不会有输出,退出码为0。
- 如果出现语法错误,分析将在第一个错误处停止,包含行号的错误信息将写入 stderr,退出代码为:
2
在bash
3
在ksh
1
在zsh
Separately, bash
, ksh
, and zsh
offer debugging options:
分别,bash
,ksh
和zsh
提供调试选项:
-v
to print each raw source code line[1]to stderr before it is executed.-x
to print each expanded simple commandto stderr before it is executed (env. var.PS4
allows tweaking the output format).
-v
在执行之前将每个原始源代码行[1]打印到 stderr。-x
在执行之前将每个扩展的简单命令打印到 stderr(环境变量PS4
允许调整输出格式)。
Combining -n
with -v
and/or -x
offers little benefit:
结合-n
使用-v
和/或-x
提供很少的好处:
With
-n
specified,-x
has no effect at all, because nothing is being executed.With
-n
specified,-v
will effectively simply printthe source code.- If there is a syntax error, there maybe benefit in the source code getting print up to the point where the error occurs; keep in mind, though that the error message produced by
-n
always includes the offending line number.
- If there is a syntax error, there maybe benefit in the source code getting print up to the point where the error occurs; keep in mind, though that the error message produced by
使用
-n
指定,-x
根本没有任何效果,因为没有执行任何操作。随着
-n
规定,-v
将有效只需打印的源代码。- 如果有语法错误,源代码打印到错误发生点可能会有好处;请记住,尽管由 产生的错误消息始终包含有问题的行号。
-n
- 如果有语法错误,源代码打印到错误发生点可能会有好处;请记住,尽管由 产生的错误消息始终包含有问题的行号。
[1] Typically, it is individual linesthat are printed, but the true unit is however many lines a given command - which may be a compound command such as while
or a command list (such as a pipeline) - spans.
[1]通常,打印的是单独的行,但真正的单位是一个给定的命令——可能是一个复合命令,如while
或命令列表(如管道)——跨越的多行。