Linux busybox sh包装器添加额外功能

Linux busybox sh包装器添加额外功能,linux,shell,busybox,Linux,Shell,Busybox,我需要一个简单的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运行脚本,但它不支持数组。很遗憾,您需要在参数中处理空格,否则这可能会起作用: #!/bin/sh Q=

我需要一个简单的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运行脚本,但它不支持数组。

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

#!/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语言编写代码,这会有点难看。

这使用了-但我从另一个答案的注释中看到,代码不应该在bash下运行(尽管bash标记最初应用于问题);这是为了在壳下运行

我几乎可以肯定它没有回答这个问题,因为考虑到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,如果设置为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重定向,您将看到相同的输出。

可以在busybox的
ash
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

我能看到支持空格的唯一方法是使用数组,但我不知道busybox sh是否支持数组?如果您想使用busybox shell运行脚本,为什么会将其标记为“bash”?当bash提供所需的功能时,为什么要使用busybox shell?因为您使用的是bash,所以不必同时使用引号和“X”丹尼斯·威廉姆森:好吧,我是在老派学校长大的;在未来25年的某个时候,我会适应的。我写的东西确实有用,而且成本差异很小(比如,无法衡量)。此外,事实上,所有POSIX shell测试操作符没有X都应该可以;但是,我已经使用了足够多的不完全符合POSIX的shell,以避免被烧坏的风险。我也是在“老学校”长大的。我的许多旧脚本中都有X。当我使用“他说不要!”作为论据时,评估将不起作用;如果我写它,也会很不高兴“他说用'ls',我就用了”。在第一种情况下,你的单引号不平衡,打乱了对话;在第二种情况下,你将执行'ls'命令。
diff…这是在
diff
命令中使用你的
acommand
脚本。作为警告,这个答案不能正确处理参数中的双引号(并且,同样地,可能会计算backticket或$()命令)。