这个 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.sh
,source 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对于高级用户,请添加“除非您知道为什么需要省略它们”。