如何在 bash shell 脚本中回显命令,但不执行它们?

ysa*_*sap 14 linux bash shell-script

有没有办法通过回显命令运行 shell 脚本实际上不执行它们?

假设我有脚本删除其名称存储在变量中的文件:

#!/bin/bash
set -v
FN="filename"
rm -f ${FN}
Run Code Online (Sandbox Code Playgroud)

添加set -v将在执行前回显以下命令:

$ ./scr.sh
FN="filename"
rm -f ${FN}
Run Code Online (Sandbox Code Playgroud)

现在,我想看看这个脚本的流程,而无需实际删除文件。IOW,我想防止对外部环境和文件系统产生任何影响。这可能吗?

我可以用一个echo命令来包装所有命令,但是对于一个很长的脚本来说很累人。

Nic*_*ton 8

没有办法单步执行脚本来查看它如何在不实际执行的情况下执行。在您的示例中,没有if语句或循环。但是在真实的脚本中,通常会有很多条件语句。将采用哪个分支通常取决于 shell 运行前一个命令时发生的情况。如果它不运行命令,shell 就无法知道它会生成什么输出或返回码是什么,而下一个条件分支或赋值语句可能依赖于此。

如果关键是您想在运行之前仔细检查脚本并了解它的作用,那么这不是一个坏主意。但实际上,最好的方法是使用lessvi或类似的东西浏览文件。

添加

如果您正在开发一个脚本并且您想第一次逐步完成它,测试逻辑但如果您有错误,实际上不会造成任何损害,我经常使用的解决方案是只修改通过将 粘贴echo到前面可能会造成任何损害的语句。

这通常适用于典型的现实生活中的脚本,因为 (a) 生成您将迭代的项目列表或您将设置变量的值通常可以在不更改文件系统的情况下生成,并且 (b) 通常足以假设如果您确实运行了该命令,它将成功。


小智 8

我认为您将不得不回显 - 但是如果您将命令放入变量中,您可以打开和关闭它。此外,该命令可以是一个函数,并且可以根据需要进行复杂处理。

#!/bin/bash
echo 'Debug'
  D=echo
  :>| testy
  ls -l testy
  $D rm -f testy
  ls -l testy
echo $'\n\nLive'
  D=
  :>| testy
  ls -l testy
  $D rm -f testy
  ls -l testy
Run Code Online (Sandbox Code Playgroud)

==================================================

!$ > ./conditional.sh
Debug
-rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy
rm -f testy
-rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy

Live
-rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy
ls: cannot access testy: No such file or directory
Run Code Online (Sandbox Code Playgroud)


par*_*ydr 5

您可以使用 bash 的 -x 选项跟踪流程,但这仍然会执行命令。

你能做的最好的事情就是把 echo 或注释掉具有外部效果的命令,比如 rm。至少您不必更改每一行。