0

i use a simple function in a script in order to ckeck if a string contains a particular substring:

#!/bin/bash 
#
subs() {
    case $2 in
         *$1*)
              return 0 ;;
         *)
              return 1 ;;
    esac
}

# example 1

res="$(grep -E '^blufoobla|^blubarbla' ~/test/file)"

subs foo "$res" || echo "blufoobla" >> ~/test/file
subs bar "$res" || echo "blubarbla" >> ~/test/file

# example 2

keym=us-whatever_foo

if subs - "$keym"; then
    echo there
else
    echo nope
fi

question 1: do i have to quote $1 in the case pattern of the function? unquoted variables in case patterns are interpreted as globs. therefore - i guess - there is no need to quote the variable in this particular case. but i'm not sure.. .

question 2: do i have to quote the first argument of the function ( subs foo "$res" or subs "foo" "$res" / subs - "$keym" or subs "-" "$keym" .. ?

i want to avoid excessive quoting.

3
  • Just out of curiosity... any reason, that you don't use something like printf '%s' "foobarbla" | grep -Fq "bar" ?
    – pLumo
    Commented Aug 10, 2021 at 11:09
  • not sure what that example 1 is meant to do. To check if lines containing those two keywords exist in the file and add them if not? You might want to do it line-by-line; that code looks like a line with blufoobla bar would match the grep and both the subs tests, and the script wouldn't add anything to the file, even though blubarbla didn't already exist there
    – ilkkachu
    Commented Aug 10, 2021 at 11:19
  • @ilkkachu thx, you are right. i have to use the -o flag too: grep -Eo '^blufoobla|^blubarbla'. concrete case: sshd_config in postinstall-script: grep -Eo '^PermitRootLogin no|^UseDNS no|^PasswordAuthentic.*no'. put it in a variable and do the subs thing. this way, i have only 4 short and well-formed lines for this task (if i exclusively use grep or test or parameter expansion , the task looks bloated, less readable, less maintainable, resp. "out-of-form"). + there are 3 other cases for this function in the original script. i have to take a look at your answer now.
    – noemata
    Commented Aug 10, 2021 at 12:36

1 Answer 1

1

do i have to quote $1 in the case pattern of the function?

depends, do you want it to be a pattern or a hard string?

I.e. with the pattern unquoted, this would match:

a='*.txt'
case file.txt in $a) echo match;; esac;

With "$a") instead, it wouldn't.

question 2: do i have to quote the first argument of the function ( subs foo "$res" or subs "foo" "$res" / subs - "$keym" or subs "-" "$keym"

You don't have to. If you know the values in the variable don't contain glob characters or IFS characters, or you know you want word splitting and globbing, then sure, the quotes aren't needed around the expansion.

But if the input comes from an unknown source, e.g. that input file here, you might want to the make script work regardless of what exactly the data is. And that requires quoting expansions like that. Yes, that's one of the things that makes the standard shell language ugly and awkward to use. Zsh is better in that regard.

The static string - isn't special to the shell, though, so quoting that doesn't do anything and isn't needed.

3
  • thanks again for your answer. pattern only. would be the lowest common denominator in bash's quoting-excess (i love my fish-scripts) : *"$1"*) ? if so, the quotes appear even more superfluous to me. but it would be bearable. sry for this trivial question, but it's all about "form" and "correctness". apropos, your comment about example 1 now leaves me in doubt, despite the -o flag. i may consider a different approach here.
    – noemata
    Commented Aug 10, 2021 at 13:10
  • @doleovit, yes, *"$a"*) if you want to find the fixed string in $a anywhere in the tested string. Quoting the asterisks would also make it look for literal asterisks.
    – ilkkachu
    Commented Aug 10, 2021 at 13:14
  • let's do it. this is the intended purpose of the function. and the solution for example 1: grep -E '^(blufoobla$|blubarbla$)' . i can't vote your answer up; this was my first question (+ migraine). have a good time.
    – noemata
    Commented Aug 10, 2021 at 14:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .