【问题标题】:busybox sh wrapper to add extra functionalitybusybox sh 包装器以添加额外的功能
【发布时间】:2009-10-20 12:07:23
【问题描述】:

我需要一个简单的 busybox sh 包装器:

IF "-Q" PARAMETER IS PROVIDED THEN  
    acommand ALL PARAMETERS BUT "-Q" 2>&1 1>/dev/null  
ELSE  
    acommand ALL PARAMETERS  
FI

参数可能包含空格。

顺便说一句,我想用busybox sh运行脚本,它不支持数组。

【问题讨论】:

  • 如果你想用busybox shell运行脚本,为什么这个标签是'bash'?当 bash 提供了你需要的功能时,你为什么要使用busybox shell?

标签: linux shell busybox


【解决方案1】:

这一切都可以在busyboxash shell 中完成:

#!/bin/sh
for i in "${@}"
do
    if [ "$i" = "-Q" ]
    then
        flagQ=1
    else
        args="$args \"$i\""
    fi
done
if [ "$flagQ" = "1" ]
then
    eval acommand "$args" 2>&1 1>/dev/null
else
    eval acommand "$args"
fi

【讨论】:

  • 当我使用“他说不要!”时,eval 将不起作用作为论据;如果我写“他说使用 `ls` 而我做到了”,我也很不高兴。在第一种情况下,你有不平衡的单引号弄乱了插曲;在第二个中,您将执行“ls”命令。
  • diff <(./myscript "he said use `ls` and I did") <(./acommand "he said use `ls` and I did") 没有区别。这也将执行lsecho "He said use `ls` and I did",但撇号是正确的。
  • ...在diff 命令中使用您的acommand 脚​​本。
  • 请注意,此答案无法正确处理参数中的双引号(并且可能再次评估反引号或 $() 命令)。
【解决方案2】:

这使用bash arrays - 但我从 cmets 看到另一个答案,代码不应该在 bash 下运行(尽管 bash 标记最初应用于问题);它旨在在busybox shell 下运行。

我几乎可以肯定它没有回答这个问题,因为鉴于busybox 的局限性,这个问题基本上无法回答。在过去,我使用了一个名为“escape”的自定义程序来构建一个参数字符串,该字符串可以被评估以获取原始参数 - 空格和所有参数。但这需要外壳外部的支持。


此解决方案仅使用“bash”。我不确定它是否是完全惯用的 bash 代码,但它可以工作。

#!/bin/bash

i=0
Qflag=0
for arg in "$@"
do
    if [ "X$arg" = "X-Q" ]
    then Qflag=1
    else args[$((i++))]=$arg
    fi
done

if [ $Qflag = 1 ]
then exec acommand "${args[@]}" 2>&1 >/dev/null
else exec acommand "${args[@]}"
fi

第一个循环使用脚本的参数构建一个数组 args,但它没有将“-Q”添加到列表中并将其存在记录在变量 Qflag 中。

最后的 if 语句说明 Qflag 是否设置为 1,如果是,则将错误从 'acommand' 发送到标准输出,并将常规标准输出发送到 /dev/null(这与如果I/O 重定向是相反的——这会将标准输出发送到 /dev/null 并将标准错误发送到同一个地方,从而强制“acommand”保持沉默)。

“exec”的使用是一种微不足道的优化,在这种情况下简化了退出状态处理。

使用在单独的行上打印其参数的“acommand”进行测试:

#!/bin/sh
for arg in "$@"
do echo "$arg"
done

并使用命令行,例如:

bash wrapper.sh -c -d 'arg with spaces'

产生输出:

-c
-d
arg with spaces

显然,在 I/O 重定向到位后,以下位置没有输出:

bash wrapper.sh -c -Q -d 'arg with spaces'

但是,如果您省略 I/O 重定向,您将看到相同的输出。

【讨论】:

  • 由于您使用的是 Bash,因此不必在测试中同时使用引号和“X” - 单独使用引号即可。
  • @Dennis Williamson:很好——我在老学校长大;在未来 25 年的某个时候,我会适应这一点。我写的确实有效,而且成本差异很小(如,无法衡量)。另外,事实上,所有的 POSIX shell 测试操作符都应该没有 X 的;但是,我已经使用了足够多的不完全符合 POSIX 标准的 shell,以免被烧毁。
  • 我也是在“老学校”长大的。我的很多旧脚本中都有 X。
【解决方案3】:

很遗憾,您需要处理参数中的空格,否则这可能会起作用:

#!/bin/sh
Q=0
ARGS=

while [ $# -ge 1 ]; do
    case $1 in
        -Q)
            Q=1
            ;;
        *)
            ARGS="$ARGS $1"
            ;;
    esac
    shift
done

if [ $Q -eq 1 ] ; then
    acommand $ARGS 2>&1 1>/dev/null
else
    acommand $ARGS
fi

编辑:

因此,此版本处理空格,但以解释反引号为代价。

#!/bin/busybox ash
Q=0
ARGS=

while [ $# -ge 1 ]; do
    case $1 in
        -Q)
            Q=1
            ;;
        *)
            ARGS="$ARGS \"$1\""
            ;;
    esac
    shift
done

if [ "$Q" -eq 1 ] ; then
    eval acommand $ARGS 2>&1 1>/dev/null
else
    eval acommand $ARGS
fi

我认为要拥有一个完整的解决方案,您将不得不用 C 对其进行编码,这会有点难看。

【讨论】:

  • 我能看到支持空格的唯一方法是使用数组 - 但我不知道busybox sh 是否支持数组?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多