bash/sh嵌套的逃生序列



我想了解如何在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 \\\\\\\" \\\" \" " "

这变得非常丑陋,老实说,我不确定您为什么要这样做,但是,嘿。筑巢!

相关内容

  • 没有找到相关文章