與POSIX sh不同的是,bash
提供了一種明確的方法來要求shell將數據轉義爲eval-safe,與printf %q
。
因此,使用bash:
$ command_str=date
$ nest() { printf 'sh -c %q\n' "$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
...等等,循環往復。
在POSIX SH,第三方庫Push可用於同一目的:
$ 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 "[email protected]"; cmd_str=${cmd_str%" "}
## in POSIX sh, using https://github.com/vaeth/push
#Push -c cmd_str sh -c "[email protected]"
if [ "$level" -gt 1 ]; then
nest "$((level - 1))" "$cmd_str"
else
printf '%s\n' "$cmd_str"
fi
}
然後:
nest 5 date
...會給您(printf %q
,VS推) ...
sh -c sh\ -c\ sh\\\ -c\\\ date
'/ bin/sh'是POSIX sh,不是現代系統上的Bourne。伯恩是一個更老的殼(70年代,90年代初)。 –
順便說一句,如果使用bash而不是POSIX sh,通用的途徑是將''printf%q''傳遞給另一個shell的任意內容。 (因此:因爲你的問題是明確詢問'/ bin/sh',所以它不應該被標記爲'bash'; bash的答案會不同)。 –
「bash/sh」與「C/C++」一樣糟糕。他們是兩種不同的語言。如果你真的需要了解兩者,他們應該得到兩個不同的問題。 –