Bash 脚本无法将变量识别为路径的一部分

Bash 脚本无法将变量识别为路径的一部分

这个 if 语句:

if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then
    OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie
else
    echo "Error: Cannot find the OSSIE aclocal files. This is not expected!"

始终默认错误消息。我知道它OSSIEHOME有一个值,因为如果我echo $OSSIEHOME从命令行执行,我会得到

/usr/local/redhawk/core

如果我将该路径硬编码到我的脚本中,它就可以正常工作。问题是,我还有一些其他更大的脚本,无法对正确的路径进行硬编码。我究竟做错了什么?

编辑: od -c <<<"$OSSIEHOME"给我这个:

0000000 / u s r / l o c a l / r e d h a
0000020 w k / c o r e \n
0000030

ls -l /usr/local/redhawk/core/share/aclocal/给了我这个:

drwxr-xr-x 2 root root 4096 Jul 19 10:02 ossie

运行脚本bash -x给出:

+ rm -f config.cache
+ '[' -e /usr/local/share/aclocal/libtool.m4 ']'
+ '[' -e /usr/share/aclocal/libtool.m4 ']'
+ /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4
+ libtoolize --force --automake
+ '[' -n ']'
+ '[' -d /share/aclocal/ossie ']'
+ echo 'Error: Cannot find the OSSIE aclocal files. This is not expected!'
Error: Cannot find the OSSIE aclocal files. This is not expected!
+ '[' -n ']'
+ aclocal -I
aclocal: error: option '-I' requires an argument
aclocal: Try '/bin/aclocal --help' for more information.
+ autoconf
+ automake --foreign --add-missing

我尝试导出OSSIEHOME以使其全球化(以防万一),但这不起作用。然后我尝试运行脚本. script.shsource script.sh问题是我需要使用 sudo 运行脚本,否则它将没有必要的权限来工作。如果我这样做,但我收到错误

sudo: source: command not found

答案1

该问题已在问题的评论中得到诊断。在我的回答中,我将解释发生了什么以及如何解决它。

代码

if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then

很危险,因为您正在使用不带引号的变量扩展。"${OSSIEHOME}"或者只是"$OSSIEHOME"扩展为变量的值,但${OSSIEHOME}外部引号被拆分为单词。特别是,如果变量为空或未设置,则运算符左侧的命令&&将扩展为[ -n ]true。您可以在执行bash -x后生成的跟踪中看到[ -n ]。看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?更多细节。从现在开始,请记住始终在变量和命令替换两边加上双引号。

if [ -n "${OSSIEHOME}" ] && [ -d "${OSSIEHOME}/share/aclocal/ossie" ]; then

这将修复损坏的错误报告。但您仍然需要确保在脚本运行时设置该变量。仅检查echo $OSSIEHOME当前 shell 中是否打印了某些内容是不够的。您需要确保该变量位于环境中。如果您只执行 run OSSIEHOME=/usr/local/redhawk/core,则仅设置 shell 变量。要设置环境变量,您需要运行export OSSIEHOME=/usr/local/redhawk/core(或OSSIEHOME=/usr/local/redhawk/core然后export OSSIEHOME)。

您补充说您正在通过 调用脚本sudo。在典型配置中,sudo 从环境中删除大多数变量。 (当只允许用户运行特定命令时,这对于安全性至关重要,但如果允许您使用 sudo 运行任意命令,这会很麻烦,而且没有任何强大的安全优势。)因此,您需要明确告诉 sudo 在以下情况下设置此变量:你运行脚本。

sudo OSSIEHOME=/usr/local/redhawk/core /path/to/your/script

如果该变量已在 shell 环境中设置并且您不想重复该值,则可以使用

sudo OSSIEHOME="$OSSIEHOME" /path/to/your/script

或者,您可能会或可能不会被允许运行sudo -E /path/to/your/script。该-E选项告诉 sudo 保留大多数环境变量。

运行source.使用 sudo 不起作用,因为这些是 shell 内置命令,而不是可执行命令。它们是 shell 内置函数,因为它们的作用是:运行脚本已经运行的同一个 shell,即它是 shell 中从文件读取命令的指令,而不是执行单独程序的指令。这对于 sudo 没有任何意义:如果脚本在同一个 shell 进程中运行,它将以相同的权限运行。

1对于高级用户,请添加“除非您知道为什么需要省略它们”。

相关内容