【问题标题】:Double expansion of shell variableshell变量的双重扩展
【发布时间】:2020-12-01 17:36:16
【问题描述】:

我有一个包含 env 变量的表,我需要从 shell 脚本中获取变量的值并为另一个 java 实用程序导出:

    command="SELECT param_value FROM tableX WHERE param_name='ABCD';"
    #This param_value is ${PATHX} and PATHX is /home/users/pathx

    PARAM_VALUE=`sqlplus -s $CONN_STRING <<- END
    SET head off;
    set feedback off;
    ${command}
    exit;
    END`

    echo ${PARAM_VALUE} | grep -q "ERROR"
    if [ $? -eq 0 ]
    then
            echo "Failed in fetching param_value "
            exit 1
    else
            #Trimming the value fetched from DB
            PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -d " " | tr -d "\n"`
            echo "Value fetched from DB=${PARAM_VALUE}" 
            #This prints ${PATHX}
            export PATH_VALUE="${PARAM_VALUE}" 
            #This is exporting PATH_VALUE as ${PATHX} instead of /home/users/pathx - WHICH IS WHERE I NEED HELP
            #If I put directly export PATH_VALUE="${PATHX}", it exports the value correctly as /home/users/pathx
    fi

搜索选项后,我尝试了以下各种选项但失败了:

export PATH_VALUE="${PARAM_VALUE}"
export PATH_VALUE=`eval echo "\$${PARAM_VALUE}"`
export PATH_VALUE=$(eval \$$PARAM_VALUE)
export PATH_VALUE=${$PARAM_VALUE}
export PATH_VALUE=${!PARAM_VALUE}
export PATH_VALUE=`echo ${PARAM_VALUE}`
export PATH_VALUE=`expr ${PARAM_VALUE}`

请建议在这种情况下可以做些什么来导出实际的扩展值 - /home/users/pathx。

【问题讨论】:

  • 请不要使用`反引号。请改用$(...)export PATH_VALUE=${!PARAM_NAME} 应该可以,你测试了吗?不要if [ $? -eq 0 ] 只是命令if echo "$PARAM_VALUE" | grep -q "ERROR"; then。使用shellcheck.net 来发现常见错误。
  • 您在脚本中的何处调用 java 应用程序?脚本永远不能修改其父进程的环境。因此,当脚本退出时,您在脚本中设置的任何环境变量都会丢失。 (这也是为什么为当前 shell 设置和导出环境变量的唯一位置是在运行配置文件中,如 .bashrc.profile 等。)因此,如果您没有从脚本调用 java 应用程序,那么您的环境变化毫无意义。
  • @KamilCuk,我也尝试过使用 $(...) 。 export PATH_VALUE=${!PARAM_NAME} 不起作用,我已经测试过了。
  • @DavidC.Rankin 我从脚本中调用 java 应用程序。我没有将 java 调用的代码放在我的问题中,因为它超出了我的主要问题的范围。
  • @thanasisp,感谢指出,这是一个复制粘贴错误,已解决问题。

标签: shell variables unix expansion


【解决方案1】:

为了让它按您期望的方式工作,sqlplus 查询响应应该是PATHX 而不是${PATHX}。修复它的一种方法是替换

PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -d " " | tr -d "\n"`

PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -dc '[:alnum:]\n\r'`

【讨论】:

    【解决方案2】:

    是的,查询响应是 ${PATHX},这是我需要扩展的环境变量。

    您可以使用eval,但eval 是邪恶的,如果值被导出,请安全使用envsubst

    PARAM_VALUE=$(envsubst <<<"$PARAM_VALUE") 
    

    【讨论】:

    • 也许您想指出(因为 envsubst 并非在每个平台上都可用)另一种方法是切换到 bashzsh,它们具有处理此问题的内置方法问题。
    • which have builtin way och,我没主意了。 bash 中的内置方式是什么?我只能想到eval周围的想法,比如sh -c "echo $PARAM_VALUE"source &lt;(echo "echo $PARAM_VALUE")等。
    • 我在想 Zsh 中的 ${(P)PARAM_VALUE} 之类的东西。还是我误解了问题所在?
    • 变量的内容${PATHX} 包括字面量${}。以下PATHX=something; PARAM_VALUE='${PATHX}'; echo ${(P)PARAM_VALUE} 打印一些数字,而不是PATHX 的内容。以下PATHX=something; PARAM_VALUE='PATHX'; echo ${(P)PARAM_VALUE} 会“工作”,但这不是手头的问题。
    • 立即获取。奇怪的设计。或者,可以摆脱这些${} 字符,正如LeadingEdger 在他的回复中所建议的那样,但是谁知道他们在数据库中使用了这种格式的其他变体......
    猜你喜欢
    • 2012-06-30
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 2017-01-27
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    相关资源
    最近更新 更多