
Ich frage eine MySQL-Datenbank nach dem Namen einer Datenbank nach einem Muster ab. Derzeit sieht meine Implementierung folgendermaßen aus:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| paste -sd ",")
Dadurch wird eine durch Kommas getrennte Liste mit Datenbanknamen zurückgegeben, die dem Muster entsprechen.
Allerdings erwarte ich eigentlich nur, dass ein Datenbankname zurückgegeben wird und ich denke, es wäre besser, einen Fehler auszugeben, wenn MySQL ein Ergebnis mit zwei Zeilen zurückgibt.
Gibt es sowas wie:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| __error_if_two_lines__ )
Antwort1
Sie können head
zum Extrahieren der ersten Zeile Folgendes verwenden:
include_databases=$(… | head -n 1)
Dadurch werden jedoch alle weiteren Zeilen stillschweigend ignoriert. Sie können stattdessen awk verwenden, um einen anderen Exit-Code zurückzugeben, wenn weitere Zeilen vorhanden sind:
include_databases=$(… | awk 'NR>1 {exit(2)} 1')
if [ $? -ne 0 ]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
fi
Oder unter set -e
:
include_databases=$(… | awk 'NR>1 {print "mysql returned multiple lines! Aborting." >"/dev/stderr"; exit(2)} 1')
Alternativ können Sie die Ausgabe in einer Variablen speichern und prüfen, ob sie einen Zeilenumbruch enthält. (Beachten Sie, dass der letzte Zeilenumbruch des Befehls nicht in die Befehlsersetzung einbezogen wird.)
include_databases=$(…)
nl='
'
case $include_databases in
*"$nl"*) echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
In ksh/bash/zsh, aber nicht in einfachem sh, können Sie dies kompakter schreiben.
include_databases=$(…)
if [[ "$include_databases" = *$'\n'* ]]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
Antwort2
Ich glaube, wc
das ist dein Freund. Nutze die Option -l
zum Zählen von Zeilen -w
und Wörtern. (siehe Manpage)
mysql --batch --skip-column-names --execute "SHOW DATABASES" | wc -w
zeigt die Anzahl der Datenbanken an.
zB sowas
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"
Hinweis: Sie sollten dieses Skript verbessern, da es viele Unterordner verwendet