1

I'm querying a mysql db for the name of a database by pattern. Currently my implementation looks like this:

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
    | paste -sd ",")

Which will rturn a comma separated list of database names that matched the pattern.

However, I actually only expect one database name to be returned and I think it would be better to error out when mysql returns a result with 2 lines.

Is there something like:

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
    | __error_if_two_lines__ )

2 Answers 2

1

You can use head to extract the first line:

include_databases=$(… | head -n 1)

However this will silently ignore any further lines. You can use awk instead to return a different exit code if there are more lines:

include_databases=$(… | awk 'NR>1 {exit(2)} 1')
if [ $? -ne 0 ]; then
  echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
fi

Or, under set -e:

include_databases=$(… | awk 'NR>1 {print "mysql returned multiple lines! Aborting." >"/dev/stderr"; exit(2)} 1')

Alternatively, you can store the output in a variable, and test whether it contains a line break. (Note that the final newline from the command is not included in the command substitution.)

include_databases=$(…)
nl='
'
case $include_databases in
  *"$nl"*) echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac

In ksh/bash/zsh, but not in plain sh, you can write this in a more compact way.

include_databases=$(…)
if [[ "$include_databases" = *$'\n'* ]]; then
  echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
1
  • Using head sounds like the most sensible thing to do, thanks for that suggestion. Was a bit stuck with that.
    – BMBM
    May 23, 2017 at 1:25
0

I think wc is your friend. Use option -l to count lines, -w to count words. (see man page)

mysql --batch --skip-column-names --execute "SHOW DATABASES" | wc -w

shows the number of databases.

e.g. something like this

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES")
numDB=$(echo $include_databases | wc -w)
[ $numDB -gt 1 ] && echo -n "$numDB dbs is more than "
echo "one db"

Hint: You should improve this script, because it uses a lot of subsheels

You must log in to answer this question.

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