bash 脚本运行带参数的命令并将完整命令记录到文件

bash 脚本运行带参数的命令并将完整命令记录到文件

我想要一个运行命令并将其附加到文件的通用脚本。

我的尝试如下(存储在名为 的可执行文件中./action)。

#!/bin/bash
#runs command and logs result to "./actions"

if "$@"; then
    echo "#"$(date)"(success)" >> ./actions
else
    read -p "Exit code is fail. Still record to ./actions (y)? " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        exit 1
    fi
    echo "#"$(date)"(failed)" >> ./actions
fi
echo "$@" >> ./actions

我遇到的问题是:

./action touch "new file"

运行正确,但 bash 仅保存

touch new file

显然touch new file与 不同touch "new file"

如何修复此脚本以正确记录带引号参数的命令?

答案1

有趣的问题。我认为你想要做的事情并不完全可能,但你可以使用Bash实现%q中可用的格式说明符来非常接近:printf

%q 导致 printf 以可重复用作 shell 输入的格式输出相应的参数。

脚本中的最后几行可能如下所示:

printf "%q\n" "$@" | tr '\n' ' ' >> actions
printf "\n" >> actions

这不会完全按照您键入的方式记录命令,而是以适合在 shell 中使用的形式记录命令,如果您键入这些记录的命令,您将获得最初预期的结果。例如,执行此操作后:

./action touch "new file"

你得到:

#Wed Sep 4 14:10:57 CEST 2019(success)
touch new\ file

或者执行此操作后:

./action echo 'one
two
three
'

你得到:

#Wed Sep 4 14:11:44 CEST 2019(success)
echo $'one\ntwo\nthree\n'

作为旁注,shellcheck报告脚本中的 2 个错误:

$ ~/.cabal/bin/shellcheck action

In action line 5:
    echo "#"$(date)"(success)" >> ./actions
            ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
            ^-- SC2046: Quote this to prevent word splitting.


In action line 13:
    echo "#"$(date)"(failed)" >> ./actions
            ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
            ^-- SC2046: Quote this to prevent word splitting.

相关内容