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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:09:23  来源:igfitidea点击:

Dry-run a potentially dangerous script?

linuxbash

提问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.confis 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 /binfolder, which would have had rather amusing implications. Of course this script required rootto 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 -nfor 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 -uwhich 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

bashdoes notoffer dry-run functionality(and neither do ksh, zsh, or any other shell I know).

bash没有提供干式运行的功能(也不做kshzsh或任何其他的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 zshoffer 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:
    • 2in bash
    • 3in ksh
    • 1in zsh
  • 如果没有语法错误,则不会有输出,退出码为0。
  • 如果出现语法错误,分析将在第一个错误处停止,包含行号的错误信息将写入 stderr,退出代码为:
    • 2bash
    • 3ksh
    • 1zsh


Separately, bash, ksh, and zshoffer debugging options:

分别,bashkshzsh提供调试选项

  • -vto print each raw source code line[1]to stderr before it is executed.

  • -xto print each expanded simple commandto stderr before it is executed (env. var. PS4allows tweaking the output format).

  • -v在执行之前将每个原始源代码行[1]打印到 stderr。

  • -x在执行之前将每个扩展的简单命令打印到 stderr(环境变量PS4允许调整输出格式)。



Combining -nwith -vand/or -xoffers little benefit:

结合-n使用-v和/或-x提供很少的好处:

  • With -nspecified, -xhas no effect at all, because nothing is being executed.

  • With -nspecified, -vwill 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
      -nalways includes the offending line number.
  • 使用-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 whileor a command list (such as a pipeline) - spans.

[1]通常,打印的是单独的,但真正的单位是一个给定的命令——可能是一个复合命令,如while或命令列表(如管道)——跨越的多行。