if statement to check $HOSTNAME in shell script
Asked Answered
D

4

51

So I want to set some paths differently depending on the host, but unfortunately it's not working. Here is my script:

if [$HOSTNAME == "foo"]; then
    echo "success"
else
    echo "failure"
fi

This is what happens:

-bash: [foo: command not found
failure

I know for certain that $HOSTNAME is foo, so I'm not sure what the problem is. I am pretty new to bash though. Any help would be appreciated! Thanks!

Dapsang answered 12/4, 2013 at 13:54 Comment(4)
Hint: the shell is whitespace sensitive. [x is different from [ x.Loring
Hint: The test operator for string equality is =, not ==, even though the latter is accepted by buggy shells in a misguided attempt to ease programmers with less error messages.Loring
@Loring can you elaborate on the attempt being misguided, it seems that == is a fairly standard equality operator syntax? I'm a software engineer now really using shell a lot these days and I'm just curious.Electrotype
@Electrotype The Standard is the Opengroup's UNIX specification and in that grammar only = is the comparison operator for test. Many years ago some shells started to make == synonymous. This made scripts using == suddenly non-portable and ill-behaved on conformant shells (of which there were many, and some still are around).Loring
L
83

The POSIX and portable way to compare strings in the shell is

if [ "$HOSTNAME" = foo ]; then
    printf '%s\n' "on the right host"
else
    printf '%s\n' "uh-oh, not on foo"
fi

A case statement may be more flexible, though:

case $HOSTNAME in
  (foo) echo "Woohoo, we're on foo!";;
  (bar) echo "Oops, bar? Are you kidding?";;
  (*)   echo "How did I get in the middle of nowhere?";;
esac
Loring answered 12/4, 2013 at 13:57 Comment(3)
One, and only one. That's POSIX. Anything else is a bogus shell, accepting more than it should, promoting the == noncompliant script disease.Loring
What is the diff between hostname and HOSTNAME? For comparison I need HOSTNAME. On wsl, hostname returns wsl and HOSTNAME the windows host.Dongola
@Loring nvm found what I was looking for.Electrotype
J
4

You're missing a space after the opening bracket. It's also good "not to parse" the variable content using double quotes:

if [ "$HOSTNAME" = "foo" ]; then 
    ...
Jube answered 12/4, 2013 at 13:56 Comment(5)
Double == is a bug. The equality operator is =. Some shells only accept it because of widespread ignorance :-)Loring
You're right that it's not 100% POSIX correct, but I always tend to use == if it works.Jube
You should rethink the "if it works" attitude. It won't work on many a popular shell, while = will work everwhere on any Unix since the epoch. One day you will find yourself on such a system. Ever heard of Solaris? And = is even less to type than ==.Loring
There are many utilities that are kind of platform specific. I do care if there's a possibility that my script won't work. When I write a simple script for myself, who cares.Jube
Attention to detail is the hallmark of professional programming. Why would anyone be less caring for their own scripting? I am caring, and I wish more people were, because it gets you in a habit of writing bullet-proof code from the start.Loring
E
2
#!/bin/bash

if [[ $(hostname) == "home" ]] || [[ $(hostname) == "home2" ]]; then
    echo "True"
fi
Ellsworthellwood answered 6/2, 2021 at 16:46 Comment(0)
M
0

Bash solution:

if [[ $HOSTNAME == 'foo' ]]; then
  echo 'yep this is foo'
else
  echo 'not foo'
fi

In regard to the response from @alper :

You can combine your logical OR (||) like this:

if [[ $(hostname) == "home" || $(hostname) == "home2" ]]; then
  echo "True"
fi

It's fine to do it the way you did, but I thought you might want to know you can save some keystrokes. One other critique is that using a subshell $() to execute the hostname command is slower than comparing against $HOSTNAME. There are valid reasons to do this in some environments, but the builtin environment variable $HOSTNAME should suffice for most simple use cases.

In response to @Jens: Bash supports the POSIX-compliant string-equality comparison operator (=), but has its own string-equality comparison operator (==) to differentiate it from the POSIX-compliant operator. This mirrors how bash's built-in test construct ([[ ]]) is doubled to differentiate it from the POSIX-compliant test contract ([ ]).

Calling bash a 'buggy shell' because it 'accepts' its own string-equality construct is a complete misrepresentation.

Saying that '==' is accepted by 'buggy shells in an attempt to ease programmers with less error messages' is totally false, not to mention bad grammar. You meant 'fewer' error messages.

Saying that '== is a bug' and 'some shells only accept it because of widespread ignorance' is completely wrong.

Solaris is being replaced with Linux more and more with each passing year in corporate environments. The majority of *nix servers run some flavor of Linux. So POSIX compliance in all shell scripts is no longer a hard requirement, and is increasingly irrelevant for a lot of environments.

Bash won the shell wars, because Linux won the *nix wars.

Microcrystalline answered 28/6 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.