问题 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 变量的建议(显然在这里没用)。否则,我发现:
连接两条路径但我不知道如何将它应用到我的情况中。此线程中第一个块的结尾对我来说返回不正确。(对于我想做的事情来说,导出似乎也有点极端:但我知道什么?)
在 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"