我想了解如何在sh
中编写嵌套的逃生序列。我必须在一个示例中进行说明,我想写类似的东西
sh -c sh -c sh -c sh -c sh -c date
预期输出:当前日期
我尝试了以下操作,可以达到2个嵌套,但丢失了:
sh -c date
Sat May 2 18:38:38 PDT 2015
sh -c "sh -c date"
Sat May 2 18:38:43 PDT 2015
sh -c "sh -c "sh -c date""
Unmatched ".
我想要一种通用方式来逃脱,就像上面所示的5个嵌套级别。
与Posix SH不同,bash
提供了一种明确的方法,要求Shell逃脱数据以进行评估,并使用printf %q
。
因此,使用bash:
$ command_str=date
$ nest() { printf 'sh -c %qn' "$1"; }
$ nest "$command_str"
sh -c date
$ nest "$(nest "$command_str")"
sh -c sh -c date
$ nest "$(nest "$(nest "$command_str")" )"
sh -c sh -c sh\ -c\ date
...等等,ad ad infinitum。
在Posix SH中,第三方库推送可以用于同一目的:
$ source push.sh
$ command_str=date
$ Push -c command_str sh -c "$command_str"; echo "$command_str"
sh -c date
$ Push -c command_str sh -c "$command_str"; echo "$command_str"
sh -c 'sh -c date'
$ Push -c command_str sh -c "$command_str"; echo "$command_str"
sh -c 'sh -c '''sh -c date''
$ Push -c command_str sh -c "$command_str"; echo "$command_str"
sh -c 'sh -c '''sh -c '''''''sh -c date'''''
...等等。
如果您想自动为任意数量的级别自动化:
nest() {
local cmd_str level >/dev/null 2>&1 ||: "in POSIX sh, local may not exist"
level=$1; shift
## in bash
printf -v cmd_str '%q ' sh -c "$@"; cmd_str=${cmd_str%" "}
## in POSIX sh, using https://github.com/vaeth/push
#Push -c cmd_str sh -c "$@"
if [ "$level" -gt 1 ]; then
nest "$((level - 1))" "$cmd_str"
else
printf '%sn' "$cmd_str"
fi
}
然后:
nest 5 date
...会给您(使用printf %q
,vs推)...
sh -c sh -c sh\ -c\ date
假设这是您的意思...
sh -c "sh -c "sh -c \" sh -c \\\" sh -c \\\\\\\" date \\\\\\\" \\\" \" " "
这变得非常丑陋,老实说,我不确定您为什么要这样做,但是,嘿。筑巢!