In Bash, how can I check if a string begins with some value? In Bash, how can I check if a string begins with some value? bash bash

In Bash, how can I check if a string begins with some value?


This snippet on the Advanced Bash Scripting Guide says:

# The == comparison operator behaves differently within a double-brackets# test than within single brackets.[[ $a == z* ]]   # True if $a starts with a "z" (wildcard matching).[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

So you had it nearly correct; you needed double brackets, not single brackets.


With regards to your second question, you can write it this way:

HOST=user1if  [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;then    echo yes1fiHOST=node001if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;then    echo yes2fi

Which will echo

yes1yes2

Bash's if syntax is hard to get used to (IMO).


If you're using a recent version of Bash (v3+), I suggest the Bash regex comparison operator =~, for example,

if [[ "$HOST" =~ ^user.* ]]; then    echo "yes"fi

To match this or that in a regex, use |, for example,

if [[ "$HOST" =~ ^user.*|^host1 ]]; then    echo "yes"fi

Note - this is 'proper' regular expression syntax.

  • user* means use and zero-or-more occurrences of r, so use and userrrr will match.
  • user.* means user and zero-or-more occurrences of any character, so user1, userX will match.
  • ^user.* means match the pattern user.* at the begin of $HOST.

If you're not familiar with regular expression syntax, try referring to this resource.

Note that the Bash =~ operator only does regular expression matching when the right hand side is UNQUOTED. If you do quote the right hand side, "any part of the pattern may be quoted to force it to be matched as a string.". You should not quote the right hand side even when doing parameter expansion.


I always try to stick with POSIX sh instead of using Bash extensions, since one of the major points of scripting is portability (besides connecting programs, not replacing them).

In sh, there is an easy way to check for an "is-prefix" condition.

case $HOST in node*)    # Your code hereesac

Given how old, arcane and crufty sh is (and Bash is not the cure: It's more complicated, less consistent and less portable), I'd like to point out a very nice functional aspect: While some syntax elements like case are built-in, the resulting constructs are no different than any other job. They can be composed in the same way:

if case $HOST in node*) true;; *) false;; esac; then    # Your code herefi

Or even shorter

if case $HOST in node*) ;; *) false;; esac; then    # Your code herefi

Or even shorter (just to present ! as a language element -- but this is bad style now)

if ! case $HOST in node*) false;; esac; then    # Your code herefi

If you like being explicit, build your own language element:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }

Isn't this actually quite nice?

if beginswith node "$HOST"; then    # Your code herefi

And since sh is basically only jobs and string-lists (and internally processes, out of which jobs are composed), we can now even do some light functional programming:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; }all() {    test=$1; shift    for i in "$@"; do        $test "$i" || return    done}all "beginswith x" x xy xyz ; checkresult  # Prints TRUEall "beginswith x" x xy abc ; checkresult  # Prints FALSE

This is elegant. Not that I'd advocate using sh for anything serious -- it breaks all too quickly on real world requirements (no lambdas, so we must use strings. But nesting function calls with strings is not possible, pipes are not possible, etc.)