首页 > 解决方案 > POSIX 等价于 prinf -v

问题描述

我有一个脚本用另一个值替换一个变量,具体取决于输入:

#!/bin/bash

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

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

这很好用,尽管我希望脚本符合 POSIX。我#!/bin/sh用于我所有的脚本,虽然printf -v是 bashism。我该如何修改这个程序?我可以使用等效的功能吗?谢谢!

标签: bashshellshposix

解决方案


read本身可以设置名称在$1. 但是,您仍然需要read ANSWER先检查响应。完成后,您可以使用readhere-document 将值传输$ANSWER到任何变量prompt请求。

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

您可以使用命令替换来确保ANSWER未在全局环境中设置。

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

推荐阅读