如何在SH(非Bash)中移除字符串子串?脚本参数处理求助
兼容POSIX sh的脚本参数处理方案
问题背景
需要修改以#!/bin/sh开头的脚本参数:检测并移除标记_learn,同时设置对应变量,剩余参数用eval处理。原代码使用bash特有的参数替换语法,触发了“bad substitution”错误,需改用POSIX sh兼容的实现。
实现方案
方案一:用sed进行字符串替换
POSIX sh没有内置的字符串全局替换语法,可借助sed移除独立的_learn标记(避免误删其他包含该字符串的参数):
#!/bin/sh bash_params="_learn _vil=bar _meet=foo" _learn_sp=False _lsp=True case "$bash_params" in *"_learn"*) _learn_sp=True _lsp=False # 处理三种情况:开头的_learn、中间的_learn、单独的_learn bash_params=$(echo "$bash_params" | sed -e 's/^_learn //' -e 's/ _learn//' -e 's/^_learn$//') ;; esac # 执行剩余参数 eval "$bash_params" # 验证结果(可选) echo "_learn_sp: $_learn_sp" echo "_lsp: $_lsp" echo "_vil: $_vil" echo "_meet: $_meet"
方案二:拆分参数遍历处理(更健壮)
将参数拆分为独立项逐个处理,能避免字符串替换的边缘问题,适配更复杂的参数格式:
#!/bin/sh bash_params="_learn _vil=bar _meet=foo" _learn_sp=False _lsp=True new_params="" # 将参数拆分为位置参数 set -- $bash_params # 遍历所有参数 while [ $# -gt 0 ]; do case "$1" in _learn) _learn_sp=True _lsp=False ;; *) # 收集非标记参数 new_params="$new_params $1" ;; esac shift done # 移除参数列表开头的空格 new_params=$(echo "$new_params" | sed 's/^ //') # 执行剩余参数 eval "$new_params" # 验证结果(可选) echo "_learn_sp: $_learn_sp" echo "_lsp: $_lsp" echo "_vil: $_vil" echo "_meet: $_meet"
注意事项
- 使用
eval时需确保参数来源安全,避免注入风险;若参数来自不可信输入,需增加参数合法性校验。 - 方案二更适合处理包含特殊字符(如引号)的参数,兼容性和健壮性优于字符串替换方案。
内容的提问来源于stack exchange,提问作者Ahmad
相关产品推荐
相关产品推荐

