2

This if statement:

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!"

Constantly defaults to the error message. I know that OSSIEHOME has a value because if I do echo $OSSIEHOME from the command line I get

/usr/local/redhawk/core

And if I then hard code that path into my script it works fine. Problem is, I have a few other, much larger scripts where going through and hard coding the correct path isn't an option. What am I doing wrong?

Edit: od -c <<<"$OSSIEHOME" gives me this:

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/ gives me this:

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

Running the script with bash -x gives:

+ 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

I tried to export OSSIEHOME to make it global (just in case) but that didn't work. I then tried to run the script at . script.sh and source script.sh problem is I need to run the script with sudo or it won't have the necessary permissions to work. if I do though I get the error

sudo: source: command not found
nb12345
  • 43
  • I wonder if there are "invisible" characters in there. What does od -c <<<"$OSSIEHOME" show you? – glenn jackman Aug 10 '17 at 15:47
  • Are you running echo $OSSIEHOME in the same environment as the terminal in which you are running the script? – user4556274 Aug 10 '17 at 15:48
  • od -c <<<"$OSSIEHOME" gives me this:

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

    – nb12345 Aug 10 '17 at 15:49
  • @user4556274 yes I am running both the script and the echo command in the same environment – nb12345 Aug 10 '17 at 15:50
  • And the output of ls -l /usr/local/redhawk/core/share/aclocal/ ? (When responding to comments, please edit your question with the additional information, rather than with another comment.) – user4556274 Aug 10 '17 at 15:53
  • And if you change your test to if [[ -d ${OSSIEHOME?}/share/aclocal/ossie ]]? – DopeGhoti Aug 10 '17 at 15:54
  • 6
    [ -n ${OSSIEHOME} ] would return true if $OSSIEHOME was empty as you forgot to quote the variable. You forgot to quote all variables actually. – Stéphane Chazelas Aug 10 '17 at 15:55
  • 2
    Try running your script with bash -x to see what happens. – Stéphane Chazelas Aug 10 '17 at 15:56
  • As @StéphaneChazelas and I suspected, your variable is not initialized. – DopeGhoti Aug 10 '17 at 16:02
  • Why would the variable not be initialized if I can see its value from the command line? – nb12345 Aug 10 '17 at 16:03
  • Your script does not inherit all variables that have been set in your current shell. – DopeGhoti Aug 10 '17 at 16:04
  • Ok I tried a couple of things. First I tried to export OSSIEHOME to make it global (just in case) but that didn't work. I then tried to run the script at . script.sh and source script.sh problem is I need to run the script with sudo or it won't have the necessary permissions to work. if I do though I get the error sudo: source: command not found – nb12345 Aug 10 '17 at 16:18
  • 3
    sudo is important information not stated in your question (contrary to your earlier comment, you were not running the script in the same environment as the echo command... unless you were running sudo echo). Try running as sudo -E (preserve environment of the original user). – user4556274 Aug 10 '17 at 16:34

1 Answers1

4

The issue has been diagnosed in comments in the question. In my answer I'll explain what's going on and how to fix it.

The code

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

is dangerous because you're using unquoted variable expansions. "${OSSIEHOME}" or just "$OSSIEHOME" expands to the value of the variable but ${OSSIEHOME} outside quotes is split into words. In particular, if the variable is empty or unset then the command to the left of the && operator expands to [ -n ] which is true. You can see in the trace produced by bash -x that [ -n ] is executed. See Why does my shell script choke on whitespace or other special characters? for more details. From now on, remember to always put double quotes around variable and command substitutions¹.

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

This will fix the broken error reporting. But you still need to ensure that the variable is set when the script runs. It isn't enough to check that echo $OSSIEHOME prints something in your current shell. You need to ensure that the variable is in the environment. If you only do run OSSIEHOME=/usr/local/redhawk/core, that sets a shell variable only. To set an environment variable, you need to run export OSSIEHOME=/usr/local/redhawk/core (or OSSIEHOME=/usr/local/redhawk/core and then export OSSIEHOME).

You add that you're invoking the script through sudo. In typical configurations, sudo removes most variables from the environment. (This is vital for security when users are only allowed to run specific commands, but it's an annoyance without any strong security benefit if you're allowed to run arbitrary commands with sudo.) So you need to explicitly tell sudo to set this variable when you run the script.

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

If the variable is already set in the shell's environment and you don't want to repeat the value, you can use

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

Alternatively, you may or may not be allowed to run sudo -E /path/to/your/script. The -E option tells sudo to preserve most environment variables.

Running source or . with sudo doesn't work because these are shell builtins, not executable commands. They are shell builtins because of what they do: run a script in the same shell that's already running, i.e. it's an instruction in the shell to go and read commands from a file, not an instruction to execute a separate program. This cannot make any sense with sudo: if the script was running in the same shell process, it would be running with the same privileges.

¹ For advanced users, add “unless you know why you need to omit them”.

  • Thanks! This is really helpful. And to clarify I didn't run the script originally with sudo just when I tried to run source or . I'll keep this in mind when editing other scripts – nb12345 Aug 11 '17 at 14:55