如何编写一个Bash函数来确认现有变量的值与用户

问题描述:

我有大量的配置变量,我希望用户为其颁发值的确认。所以,可能会有一些变量指定存在的运行编号,我希望脚本询问用户变量的当前值是否正确。如果用户回应该值不正确,该脚本将请求一个新值并将其分配给该变量。如何编写一个Bash函数来确认现有变量的值与用户

我已经为此做了一个初始尝试,但是它的运行有一些困难;它摊位。我会重视解决问题的一些帮助,以及对我使用的方法的任何批评。代码如下:

confirmVariableValue(){ 
    variableName="${1}" 
    variableValue="${!variableName}" 
    while [[ "${userInput}" != "n" && "${userInput}" != "y" ]]; do 
     echo "variable "${variableName}" value: "${variableValue}"" 
     echo "Is this correct? (y: continue/n: change it/other: exit)" 
     read userInput 
     # Make the user input lowercase. 
     userInput="$(echo "${userInput}" | sed 's/\(.*\)/\L\1/')" 
     # If the user input is "n", request a new value for the variable. If the 
     # user input is anything other than "y" or "n", exit. If the user input 
     # is "y", then the user confirmation loop ends. 
     if [[ "${userInput}" == "n" ]]; then 
      echo "enter variable "${variableName}" value:" 
      read variableValue 
     elif [[ "${userInput}" != "y" && "${userInput}" != "n" ]]; then 
      echo "terminating" 
      exit 0 
     fi 
    done 
    echo "${variableValue}" 
} 

myVariable="run_2014-09-23T1909" 
echo "--------------------------------------------------------------------------------" 
echo "initial variable value: "${myVariable}"" 
myVariable="$(confirmVariableValue "myVariable")" 
echo "final variable value: "${myVariable}"" 
echo "--------------------------------------------------------------------------------" 
+0

这个问题似乎是脱离主题,因为它是关于代码审查。 – chepner 2014-09-23 18:26:56

+0

不是。代码不起作用。我不知道为什么,并要求帮助。 – d3pd 2014-09-23 18:29:06

+0

@chepner:只有部分是代码审查。有一个错误报告:“它停滞”。 – bishop 2014-09-23 18:29:18

的问题是在这里:

myVariable="$(confirmVariableValue "myVariable")" 

您的问题,像

echo "Is this correct? (y: continue/n: change it/other: exit)" 

正在进入的myVariable,而不是到屏幕上。

尝试将问题打印到STDERR或任何其他文件描述符,但STDOUT。

基于意见的评论:我会不满意这样的配置脚本。这太方便了。对我来说是更好的:

  • 打印出来的描述和默认值
  • ,并要求Press Enter for confirm or enter a new value or <something> for exit>

您还可以使用以下方法:

  • 使用bash的readline用于read命令的库与-e
  • 使用-i value用于设置编辑
  • 默认值使用printf -v variable打印成变量,所以你不需要使用var=$(...)也没有任何(潜在的)危险的eval ...

例如:

err() { echo "[email protected]" >&2; return 1; } 

getval() { 
    while : 
    do 
     read -e -i "${!1}" -p "$1>" inp 
     case "$inp" in 
      Q|q) err "Quitting...." || return 1 ;; 
      "") err "Must enter some value" ;; 
      *) 
       #validate the input here 

       #and print the new value into the variable 
       printf -v "$1" "%s" "$inp" 
       return 0 
       ;; 
     esac 
    done 
} 

somevariable=val1 
anotherone=val2 
x=val3 

for var in somevariable anotherone x 
do 
    getval "$var" || exit 
    echo "new value for $var is: =${!var}=" 
done 
+0

哦,我不知道'printf -v'。棒极了! – bishop 2014-09-23 19:34:43

+0

啊,这非常漂亮。感谢您对问题的明确解释以及不仅更加用户友好,而且代码效率更高的解决方案。 – d3pd 2014-09-23 20:08:09

+0

@ d3pd乐于帮助。 ;) – jm666 2014-09-23 20:12:03

我不会让他们回答“是”,然后输入新值。只要他们输入新值,如果他们想要一个,或者留空以接受默认值。

这个小功能可以让您在一个电话设置多个变量:

function confirm() { 
    echo "Confirming values for several variables." 

    for var; do 
     read -p "$var = ${!var} ... leave blank to accept or enter a new value: " 
     case $REPLY in 
     "") # empty use default 
      ;; 
     *) # not empty, set the variable using printf -v 
      printf -v "$var" "$REPLY" 
      ;; 
     esac 
    done 
} 

使用像这样:

$ foo='foo_default_value' 
$ bar='default_for_bar' 
$ confirm foo bar 
Confirming values for several variables. 

foo = foo_default_value ... leave blank to accept or enter a new value: bar 
bar = default_for_bar ... leave blank to accept or enter a new value: 

foo=[bar], bar=[default_for_bar] 

当然,如果空白可以是默认的,那么你就需要考虑对于那个,就像@ jm666使用read -i

+0

当用户输入输入时使用'eval'可能会有点危险...(人为因素,错误...) – jm666 2014-09-23 19:25:14

+0

@ jm666:是的。现在我知道'printf -v'(感谢您的提示!),我已经完全消除了'eval'的最后合理使用。 – bishop 2014-09-23 19:39:55

+0

:)也检查'declare'(typeset)。还允许设置变量。高兴地帮助:) – jm666 2014-09-23 19:44:05