Skip to content
shellhacks.dev
Shell Scripting

Test for a substring without double brackets

Test for a substring in POSIX sh with case $s in *sub*) instead of [[ ]]. Quote the variable inside the pattern, or its glob characters are matched as patterns.

1 min read
Summarize in AI

The script runs under /bin/sh, which has no [[ $s == *sub* ]], and you need to know whether one string contains another.

Shell
s="hello world"
sub=wor
case $s in
  *"$sub"*) echo "contains $sub" ;;
  *) echo "no $sub" ;;
esac
sub='l*o'
case $s in
  *"$sub"*) echo "quoted: matched" ;;
  *) echo "quoted: no match" ;;
esac
case $s in
  *$sub*) echo "unquoted: matched" ;;
  *) echo "unquoted: no match" ;;
esac
Text
contains wor
quoted: no match
unquoted: matched

A case pattern is a shell glob, and a star on each side turns it into a contains test. It is part of the POSIX shell grammar, so it runs in dash, busybox and every other sh. Quoting the variable inside the pattern makes its value literal, which is why the quoted test looks for the three characters l, star and o and fails, while the unquoted one treats the star as a wildcard.

The test is case sensitive, and a pattern cannot be a regular expression. If the substring may hold glob characters and you want them literal, quote it every time. For anything beyond contains, starts with and ends with, use grep -q or move the script to Bash.

Share

More snippets

Shell Scripting

Test for a prefix without double brackets

Test for a prefix in POSIX sh with a case pattern such as release-*), which works in dash and every other shell where double brackets are a syntax error.

1 min read
Shell Scripting

Check if a command exists in POSIX sh

Check that a command exists with command -v in POSIX sh. It is a builtin, it sees functions and builtins, and which does not.

1 min read
Shell Scripting

Replace an array with positional parameters

POSIX sh has no arrays, but set -- a b c turns the positional parameters into one, and "$@" expands each element as its own word without splitting.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.