当此代码包含变量赋值、循环和来自标准输入的输入时,将 bash 脚本分隔为下标

Separating bash script into subscripts when this code contains variable assignments, loops and input from stdin

我正在尝试将我的脚本分成更小的部分,以使其更有条理和可读性。

我想将一些代码(包含 while 循环、变量赋值和用户输入)放入另一个文件中。下面是我的代码示例。它的性能完全符合预期。

有效的脚本

var1="hello"
var2="world"
echo "Defaults: Var1(a)-$var1 Var2(b)-$var2"
read -p "Change Defaults? ";
while [ $REPLY != "n" ]
do
        if [ $REPLY == "a" ]
        then
             read -p "Var1 = "
             var1=$REPLY
        elif [ $REPLY == "b" ]
        then
             read -p "Var2 = "
             var2=$REPLY
        fi
        read -p "Change Defaults? ";
done
echo "$var1 $var2"

我希望我的脚本执行相同的操作,但外观和结构不同

我希望脚本看起来像什么

var1="hello"
var2="world"
echo "Defaults: Var1(a)-$var1 Var2(b)-$var2"
cmd=$(cat other_file.txt)
eval $cmd
echo "$var1 $var2"

其中 other_file.txt 包含

read -p "Change Defaults? ";
while [ $REPLY != "n" ]
do
        if [ $REPLY == "a" ]
        then
             read -p "Var1 = "
             var1=$REPLY
        elif [ $REPLY == "b" ]
        then 
             read -p "Var2 = "
             var2=$REPLY
        fi
        read -p "Change Defaults? ";
done

使用 .(又名 source)导入函数定义。

other_file.bash 将包含(有一些改进)

foo () {
    local REPLY
    read -p "Change Defaults? "
    while [[ $REPLY != n ]]
    do
        if [[ $REPLY == a ]]
        then
             read -p "Var1 = " var1
        elif [[ $REPLY == b ]]
        then 
             read -p "Var2 = " var2
        fi
        read -p "Change Defaults? "
    done
}

并且在您的脚本中:

. otherfile.bash

var1="hello"
var2="world"
echo "Defaults: Var1(a)-$var1 Var2(b)-$var2"
foo
echo "$var1 $var2"

从移动函数中的公共代码开始。 当函数正常工作时,您可以将其移动到包含文件中。我编了个名字 "include",因为它看起来像其他语言。
一个包含文件也可以被其他文件包含,因此请确保您在 "deploying" 进入包含文件之前已经很好地测试了您的功能。
包含文件可以通过获取它来包含(使用 source includefile. includefile)。您可能希望设置一个仅包含文件的文件夹。我有一个包含子目录 binshlibconfigsql 的项目。 shlib 文件夹包含所有包含文件。 当你做一个功能时,你可以花更多的时间在它能做的事情上。我会用

改变你的 changedefault 循环
changevars() {
   if [ $# -eq 0 ]; then
      echo "${FUNCNAME} should be called with at least 1 argument"
      return
   fi
  PS3="Change Defaults (n to quit)?"
  select opt in "$@"
  do
     if [[ $REPLY = n ]]; then
        break;
     fi
     [[ $REPLY =~ ^[0-9]+$ ]] && [ $REPLY -le  $# ] &&
        read -p "$opt (${!opt}) = " ${opt}
   done
}

并用

调用这个函数
source yourpath/shlib/util.sh
var1="hello"
var2="world"
echo "Defaults: Var1(a)-$var1 Var2(b)-$var2"

changevars var1 var2

echo "$var1 $var2"