Bash 如何将未计算的变量传递给shell脚本,并让脚本在获取另一个脚本后对其进行计算?

Bash 如何将未计算的变量传递给shell脚本,并让脚本在获取另一个脚本后对其进行计算?,bash,shell,Bash,Shell,我有一个脚本正在寻找第二个脚本,需要执行以下操作: 我想向第一个脚本传入一个变量名,如下所示:sh firstScript.sh variable=$variableName 然后,第一个脚本将生成第二个脚本,其中包含variableName的值 然后我将打印计算的变量 我知道我可以做\$variableName之类的事情来传递变量名,但我不知道如何让第一个脚本使用第二个脚本中导出的变量计算变量。我错过了什么?我希望这就是你想要的: firstScript.sh varname="$1" i

我有一个脚本正在寻找第二个脚本,需要执行以下操作:

  • 我想向第一个脚本传入一个变量名,如下所示:sh firstScript.sh variable=$variableName
  • 然后,第一个脚本将生成第二个脚本,其中包含variableName的值
  • 然后我将打印计算的变量

我知道我可以做\$variableName之类的事情来传递变量名,但我不知道如何让第一个脚本使用第二个脚本中导出的变量计算变量。我错过了什么?

我希望这就是你想要的:

firstScript.sh

varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

declare -n ref="$varname"
echo "varname=$varname value=$ref"
varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

echo "varname=$varname value=${!varname}"
secondScript.sh

foo=2
然后使用以下命令执行脚本:

./firstScript.sh foo
输出:

varname=foo value=2
declare
-n
选项创建对另一个变量的引用。 bash版本应为4.3或更高版本,以享受该功能

[备选方案]

您还可以将
firstScript.sh
编写为:

firstScript.sh

varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

declare -n ref="$varname"
echo "varname=$varname value=$ref"
varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

echo "varname=$varname value=${!varname}"
这将产生相同的结果

${!varname}
符号称为
间接扩展
,其中
varname
扩展为变量名。
它从bash2开始引入


希望这有帮助。

我希望这就是您想要的:

firstScript.sh

varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

declare -n ref="$varname"
echo "varname=$varname value=$ref"
varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

echo "varname=$varname value=${!varname}"
secondScript.sh

foo=2
然后使用以下命令执行脚本:

./firstScript.sh foo
输出:

varname=foo value=2
declare
-n
选项创建对另一个变量的引用。 bash版本应为4.3或更高版本,以享受该功能

[备选方案]

您还可以将
firstScript.sh
编写为:

firstScript.sh

varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

declare -n ref="$varname"
echo "varname=$varname value=$ref"
varname="$1"
if [[ -z $varname ]]; then
    echo "usage: $0 varname"
    exit
fi
source ./secondScript.sh

echo "varname=$varname value=${!varname}"
这将产生相同的结果

${!varname}
符号称为
间接扩展
,其中
varname
扩展为变量名。
它从bash2开始引入


希望这能有所帮助。

以下是我最后要做的:

我传递整个字符串,变量嵌入在字符串的中间,如:

sh firstScript.sh--message=“这是一条消息\${variableName}”

在第一个脚本中,我将执行以下步骤:

  • 将整个字符串提取到数组中
  • 拉出嵌入的变量
  • 根据源脚本评估嵌入变量
  • 执行字符串替换以将值放入原始字符串中
  • 当我完成时,它看起来是这样的:

    IFS=';' args=(${@//--/;}); unset IFS
    
    source secondScript.sh
    
    case ${arg^^} in
      MESSAGE=*)
        message="${arg#*=}"
        messageVars=$(echo ${message} | grep -o "\${\w*}")
    
        for messageVar in ${messageVars[*]}; do
          messageVar=${messageVar#*\{}
          messageVar=${messageVar%\}*}
          messageVarVal=${!messageVar}
    
          echo "messageVar: ${messageVar}"
          echo "messageVarVal: ${messageVarVal}"
          message=${message//"\${${messageVar}}"/"${messageVarVal}"}
        done
    
        echo "Message: ${message}"
      ;;
    esac
    

    以下是我最后要做的:

    我传递整个字符串,变量嵌入在字符串的中间,如:

    sh firstScript.sh--message=“这是一条消息\${variableName}”

    在第一个脚本中,我将执行以下步骤:

  • 将整个字符串提取到数组中
  • 拉出嵌入的变量
  • 根据源脚本评估嵌入变量
  • 执行字符串替换以将值放入原始字符串中
  • 当我完成时,它看起来是这样的:

    IFS=';' args=(${@//--/;}); unset IFS
    
    source secondScript.sh
    
    case ${arg^^} in
      MESSAGE=*)
        message="${arg#*=}"
        messageVars=$(echo ${message} | grep -o "\${\w*}")
    
        for messageVar in ${messageVars[*]}; do
          messageVar=${messageVar#*\{}
          messageVar=${messageVar%\}*}
          messageVarVal=${!messageVar}
    
          echo "messageVar: ${messageVar}"
          echo "messageVarVal: ${messageVarVal}"
          message=${message//"\${${messageVar}}"/"${messageVarVal}"}
        done
    
        echo "Message: ${message}"
      ;;
    esac
    

    你可以
    eval
    一个字符串,将其解释为shell命令。这个字符串被标记为
    ssh
    ——这与这个问题有什么关系?@thatotherguy-你的回答为我指明了正确的方向。我应该在原始的帖子中提到的,并且没有想到变量是在字符串的中间,像这样:SH FrestScript。s=消息=“这是一个消息\ ${VabuabLeNAME}”,在这种情况下,EVE将不起作用,但是我可以拔出字符串中的所有变量,并使用EVE来评估每个变量+做一个字符串替换。谢谢你的建议!你可以
    eval
    一个字符串,将其解释为shell命令。这个字符串被标记为
    ssh
    ——这与这个问题有什么关系?@thatotherguy-你的回答为我指明了正确的方向。我应该在原始的帖子中提到的,并且没有想到变量是在字符串的中间,像这样:SH FrestScript。s=消息=“这是一个消息\ ${VabuabLeNAME}”,在这种情况下,EVE将不起作用,但是我可以拔出字符串中的所有变量,并使用EVE来评估每个变量+做一个字符串替换。谢谢你的建议!这看起来非常接近我所需要的,但是我使用的是bashv4.1.2&没有-n选项。“不过这是一个很好的建议。”克丽珊德利感谢您的回复。我已经用另一个选项更新了我的答案,该选项将与您的bash一起使用。我应该把它包括在我以前的回答中。请你测试一下好吗?BR,这看起来非常接近我所需要的,但是我使用的是bashv4.1.2&没有-n选项。“不过这是一个很好的建议。”克丽珊德利感谢您的回复。我已经用另一个选项更新了我的答案,该选项将与您的bash一起使用。我应该把它包括在我以前的回答中。请你测试一下好吗?BR,${arrayName[*]}中x的
    基本上总是错误的;这与“${arrayName[@]}”中x的
    之间唯一的语义差异是严格不可取的。${arrayName[*]}
    中x的
    基本上总是错误的;这与“${arrayName[@]}”
    中x的
    之间唯一的语义差异是严格不可取的。