You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

POSIX兼容Shell环境下printf -v特性的等效实现方案咨询

POSIX兼容版Shell脚本修改方案

你原来的脚本用到了两个Bash专属特性(bashism),对应替换为POSIX标准语法即可实现兼容:

  • printf -v:Bash独有,用于直接给指定变量赋值,未纳入POSIX标准
  • read -p:Bash独有,用于同时输出提示和读取输入,POSIX标准read无该参数

方案1:eval实现动态变量赋值(推荐,完全匹配原逻辑)

该方案和你原有脚本的调用逻辑完全一致,不需要调整外部调用方式:

#!/bin/sh

prompt()
{
    target_var="$1"
    while true; do
        # 提示信息输出到stderr,避免干扰标准输出
        printf "Do you wish to install this program? " >&2
        read ANSWER
        case "$ANSWER" in
            [Yy]* )
                eval "$target_var=\"true\""
                break
                ;;
            [Nn]* )
                eval "$target_var=\"false\""
                break
                ;;
            * )
                echo "Please answer yes or no." >&2
                ;;
        esac
    done
}

prompt "QUESTION"
if [ "$QUESTION" = "true" ]; then
    echo "SUCCESS"
elif [ "$QUESTION" = "false" ]; then
    echo "FAILURE"
fi

说明

此处eval的写法完全安全:因为传入的目标变量名是脚本可控的固定值,不存在注入风险,执行时会先将$target_var替换为实际变量名(如QUESTION),最终等效执行QUESTION="true",和原printf -v效果完全一致。


方案2:命令替换捕获返回值(无eval)

如果你不想使用eval,可以通过命令替换捕获函数输出作为返回值,写法如下:

#!/bin/sh

prompt()
{
    while true; do
        printf "Do you wish to install this program? " >&2
        read ANSWER
        case "$ANSWER" in
            [Yy]* ) echo "true"; break;;
            [Nn]* ) echo "false"; break;;
            * ) echo "Please answer yes or no." >&2;;
        esac
    done
}

# 捕获函数stdout输出赋值给变量
QUESTION=$(prompt)
if [ "$QUESTION" = "true" ]; then
    echo "SUCCESS"
elif [ "$QUESTION" = "false" ]; then
    echo "FAILURE"
fi

说明

该方案需要注意:函数内所有用户提示、错误信息必须输出到stderr(加>&2),只有最终需要返回的结果输出到stdout,避免被命令替换捕获无关内容。


内容的提问来源于stack exchange,提问作者user15885911

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 08:18:00