在 bash 脚本中实现试运行

tro*_*ken 5 bash shell scripting eval function

我正在寻找一种优雅的方法来在我的一个 bash 脚本中实现试运行。我找到了多种方法来做到这一点,但没有一个适合我的需要。

其中之一是编写一个空运行函数,如下所示: https: //gist.github.com/pablochacin/32442fbbdb99165d6f7c

但我想执行的一些命令包括管道,并且此方法与管道不兼容。例如,我想在试运行中执行此操作:

tar cf - drytestfile | 7z a -m0=lzma2 -mx=9 -mmt=$nbCores -si drytestfile.tar.7z | tee -a /tmp/testlog
Run Code Online (Sandbox Code Playgroud)

使用上面的方法,我将在我的脚本中使用它,其中 $DRYRUN 包含对所有参数进行回显的函数的名称:

$DRYRUN tar cf - drytestfile | 7z a -m0=lzma2 -mx=9 -mmt=$nbCores -si drytestfile.tar.7z | tee -a /tmp/testlog
Run Code Online (Sandbox Code Playgroud)

当然,这将在命令的第一部分(即 tar)上运行该函数,并将该函数的结果提供给 7z。不是我真正想要的。

也许与 eval 命令有关,但我仍然不知道如何实现它......有什么想法吗?

Pop*_*dic 7

由于您正在使用管道,因此您需要为该行中的所有命令添加“$DRYRUN”。如果您只是在所有命令前面添加 $DRYRUN,那么它就会起作用,但您只会看到最后一个命令的输出。如果你想显示所有命令,一种方法是更改​​ dryrun 函数,即(根据 Charles Duffy 评论编辑):

dryrun() {
    if [[ ! -t 0 ]]
    then
        cat
    fi
    printf -v cmd_str '%q ' "$@"; echo "DRYRUN: Not executing $cmd_str" >&2
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

$DRYRUN tar cf - drytestfile | \
$DRYRUN 7z a -m0=lzma2 -mx=9 -mmt=$nbCores -si drytestfile.tar.7z | \
$DRYRUN tee -a /tmp/testlog
Run Code Online (Sandbox Code Playgroud)

例如:

dryrun echo "hello" | \
dryrun echo "world" | \
dryrun echo "foo" | \
dryrun echo "bar"
Run Code Online (Sandbox Code Playgroud)

将产生:

DRYRUN: Not executing command echo hello
DRYRUN: Not executing command echo world
DRYRUN: Not executing command echo foo
DRYRUN: Not executing command echo bar
Run Code Online (Sandbox Code Playgroud)

  • `printf -v cmd_str '%q' "$@"; echo "DRYRUN: 不执行 $cmd_str" >&2` 将为您的命令提供更准确的描述。将“$@”放入字符串中将导致输出不准确 (2认同)
  • 顺便说一句,“function foo() {”正在以一种与两者都不兼容的方式组合传统的 ksh 和 POSIX sh 函数声明语法。选择其中之一,如 http://wiki.bash-hackers.org/scripting/obsolete 中所述 (2认同)