在连接两个变量时,系统会扩展结果路径并返回意外结果。如何防止这种情况发生?

在连接两个变量时,系统会扩展结果路径并返回意外结果。如何防止这种情况发生?

问题 2.0:

给出代码:

SSLPasswordFilePath="$SSLFilesDir$SSLPasswordFile"

当我跑步时:

"$SSLPasswordFilePath"

我得到了这个意想不到的结果:

/tmp/ConfigFiles/SSL/Password.txt: line 1: *************redactedsuff*************: command not found

根据我下面得到的评论(来自问题的 1 版)以及我对 bash 的了解,我预计返回以下内容:

/tmp/ConfigFiles/SSL/Password.txt

我引用的变量如下:

SSLFilesDir="/tmp/ConfigFiles/SSL/" 
SSLPasswordFile="Password.txt"

我发现我可以使用 echo 来获得预期的结果:

echo "$SSLPasswordFilePath"

但是当我尝试将该值强制放入变量中时(注意“echo”和“$()”)

SSLPasswordFilePath=$(echo "$SSLFilesDir$SSLPasswordFile")

然后通过以下方式调用变量

"$SSLPasswordFilePath"

我仍然得到了意想不到的长期结果。

为了解决这个问题,我尝试过:

"$SSLPasswordFilePath" | awk '{printf $1}'

但它打印出相同的意外字符串,所以......我仍然被卡住了。

我搜索了整个精彩的网络,最普遍的解决方案是关于如何编辑 PATH 变量的建议(显然在这里没用)。否则,我发现:

  1. 连接两条路径但我不知道如何将它应用到我的情况中。此线程中第一个块的结尾对我来说返回不正确。(对于我想做的事情来说,导出似乎也有点极端:但我知道什么?)

  2. 在 Unix 和 Linux 上我们如何防止参数扩展?这不是我想要的,因为它涉及文字解释,并且我希望变量能够解析为完整的路径。

再次,在此之前,我能够使用简单的“将其放入变量中”方法,并且它有效。(当然,它们都是目录,因此不能以相同的方式打印。)

感谢大家提供的任何链接/建议。

编辑:我将多次使用该代码。除了一个实例外,它将用于设置 REST API 的值:

sudo fmsadmin -u ${ConsoleUser} -p ${ConsolePassword} certificate import -y "$SSLSignedCertPath" \
    --intermediateCA "$SSSLIntermediatePath" \
    --keyfile "$SSLKeyFilePath" \
    --keyfilepass ${SSLPassword}

对于另一个例子,我稍后将简单地从文件中获取值:

SSLPassword=$(sudo cat ${SSLPasswordFilePath})

编辑2 Artur:我想我不明白你做的事情。我对 bash 还不熟悉,所以当你说我给出了答案时,我可能不知道我在说什么。我理解关于字符串连接的部分(你说我做对了)。我不明白执行位是如何关联的。

首先,我不是在脚本中,而是在终端中输入的,所以./yourscript.sh: line xx: /tmp/ConfigFiles/SSL/Password.txt: Permission denied返回的结果仍然是出乎意料的。出乎意料的结果中的“第 1 行”是文本文件内容的第一行,也是唯一一行。

我的问题不是“未找到命令”,而是部分中路径后面的内容,我将其标记为“意外结果”。据我了解:当我用双引号连接两个字符串时,当我在命令行中/tmp/ConfigFile/SSL/Password.txt输入代码时,它应该会返回。"$SSLPasswordFilePath"

也许您的意思是执行位是导致文件打印成这样的原因?但根据您所展示的内容,当设置变量并将其放入 CLI/tmp/ConfigFiles/SSL/Password.txt: line 1: *************redactedsuff*************: command not found时,关闭执行位不会给我想要的返回值。"$SSLPasswordFilePath"

因此,如果执行位是读取文件的内容,那么当我像这样引用它时,如何让它仅返回变量中的字面内容:"$SSLPasswordFilePath"?对于这种情况,这只是自然行为吗?

答案1

我有点难以理解您的确切问题,因为您基本上已经自己给出了答案。

字符串连接

Bash 中的字符串连接非常简单,因为您基本上只需将变量排列在双引号内。

所以你做了什么:

InstallDir="/tmp/ConfigFiles/"
SSLFolder="SSL/"
SSLFilesDir="$InstallDir$SSLFolder"

正是正确的方法,/tmp/ConfigFiles/SSL/如果您调用命令echo "$SSLFilesDir"(扩展为echo "/tmp/ConfigFiles/SSL/"),将给出结果。

更好的可读性

不过,我更喜欢使用花括号连接变量,因为这可以增加脚本的可读性。

所以我个人会使用:

InstallDir="/tmp/ConfigFiles/"
SSLFolder="SSL/"
SSLFilesDir="${InstallDir}${SSLFolder}"

这给出了完全相同的结果,但在脚本内部更容易读取。

使用变量

如果您不需要将连接的字符串分配给新变量,则只需使用命令即可,例如您可以执行以下操作:

ls "${InstallDir}${SSLFolder}"

运行命令ls /tmp/ConfigFiles/SSL/,或者:

cat "${InstallDir}${SSLFolder}${SSLPasswordFile}"

运行命令cat /tmp/ConfigFiles/SSL/Password.txt

为什么您会收到该特定错误消息

我还可以告诉你一件事:你的文件/tmp/ConfigFiles/SSL/Password.txt执行属性设置。我怎么知道这个?

因为 Bash 成功运行它作为命令.尝试运行:

chmod -x /tmp/ConfigFiles/SSL/Password.txt

现在再次运行脚本。这次错误消息将有所不同,您将得到:

./yourscript.sh: line xx: /tmp/ConfigFiles/SSL/Password.txt: Permission denied

或者从命令行运行:

-bash: /tmp/ConfigFiles/SSL/Password.txt: Permission denied

这是因为您仍尝试将其作为命令运行,但现在该文件(Bash 之前认为是脚本)没有执行属性,因此命令失败。

您所做的完全相当于/tmp/ConfigFiles/SSL/Password.txt从命令行运行 -command not found由于它不是脚本,因此会出现错误。

最后的话

当我像这样引用它时,如何让它仅返回变量中的字面内容:"$SSLPasswordFilePath"?对于这种情况,这只是自然行为吗?

如果您希望 Bash 执行此操作,您可以分叉代码并创建自己的 Bash 品牌,使其按您想要的方式工作。您描述的不是 Bash 的工作方式,您不能强迫它以任何其他方式工作,除非您创建自己的版本。要显示变量中的内容,请使用echo "$SSLPasswordFilePath"

答案2

使用类似

echo "$SSLFilesDir$SSLPasswordFile"

或者

NewVar="$SSLFilesDir$SSLPasswordFile"
echo "$Newvar"

相关内容