在bash脚本问题中将命令设置为变量

时间:2019-05-13 19:28:45

标签: bash

尝试将命令作为变量运行,但结果却很奇怪

预期结果“ 1”:

grep -i nosuid /etc/fstab | grep -iq nfs 
echo $?
1

作为可变命令的意外结果:

cmd="grep -i nosuid /etc/fstab | grep -iq nfs"
$cmd
echo $?
0

似乎返回0,因为该命令是正确的而不是实际结果。如何做得更好?

2 个答案:

答案 0 :(得分:4)

您只能执行一个存储在变量中的命令。管道作为参数传递给第一个grep

示例

$ printArgs() { printf %s\\n "$@"; }
# Two commands. The 1st command has parameters "a" and "b".
# The 2nd command prints stdin from the first command.
$ printArgs a b | cat
a
b
$ cmd='printArgs a b | cat'
# Only one command with parameters "a", "b", "|", and "cat".
$ $cmd
a
b
|
cat
  

如何更好地做到这一点?

不要使用变量执行命令。 使用功能。

$ cmd() { grep -i nosuid /etc/fstab | grep -iq nfs; }
$ cmd
$ echo $?
1

解决实际问题的方法

对于您的实际问题,我看到了三种选择:

  • 在陷阱中使用DEBUG陷阱和BASH_COMMAND变量。
  • 为脚本启用bash的历史记录功能,并使用hist命令。
  • 使用接受命令字符串并使用eval执行命令的函数。

关于对最后一种方法的评论:您只需要一个函数。像

execAndLog() {
    description="$1"
    shift
    if eval "$*"; then
        info="PASSED: $description: $*"
        passed+=("${FUNCNAME[1]}")
    else
       info="FAILED: $description: $*"
       failed+=("${FUNCNAME[1]}")
    done
}

您可以按以下方式使用此功能

execAndLog 'Scanned system' 'grep -i nfs /etc/fstab | grep -iq noexec'

第一个参数是日志的描述,其余参数是要执行的命令。

答案 1 :(得分:1)

使用<li-rating id="liRatingFontAwesome"></li-rating> var liRating = document.getElementById("liRatingFontAwesome"); setTimeout(() => liRating.setSvgString(), 2000); bash -x将允许您查看bash执行的操作:

set -x

如您所见,管道> cmd="grep -i nosuid /etc/fstab | grep -iq nfs" > set -x > $cmd + grep -i nosuid /etc/fstab '|' grep -iq nfs 作为参数传递给第一个grep命令。