Mysql.inc.sh
Aller à la navigation
Aller à la recherche
| Fiche express | |
|---|---|
| Type | Bibliothèque bash pour requêtage MySQL en script |
| Langage | Bash + Perl (parsing des résultats) |
| Voir aussi | Mysql config editor · Mysqldump |
mysql.inc.sh est une petite bibliothèque bash à inclure (source) dans un script, fournissant quelques fonctions d'aide pour exécuter des requêtes MySQL et exploiter leurs résultats sans réinventer le parsing à chaque script.
Avertissement sécurité : ces fonctions passent le mot de passe en argument de commande (--password=$password), ce qui l'expose en clair dans la liste des processus (ps aux) le temps de l'exécution, à tout autre utilisateur du système. Pour un usage en production, préférer mysql_config_editor (login-path) ou un fichier ~/.my.cnf à permissions restreintes plutôt que ce passage explicite du mot de passe.
Chargement dans un script
test -f ./mysql.inc.sh && source ./mysql.inc.sh || exit 1
Fonctions fournies
- rc_mysql_query
(status, host, user, password, database, query)— exécute une requête. Pour les instructionsINSERT/UPDATE/REPLACE/DELETE/DROP, retourne vrai/faux selon la présence d'une erreur ; pour les autres (SELECT,SHOW,DESCRIBE...), retourne le résultat. - rc_mysql_status
(host, user, password, database, table, clé)— exécuteSHOW TABLE STATUS LIKE '<table>'et extrait la valeur d'une colonne donnée (par exempleauto_increment). - mysql_fetch_rows
(données brutes)— convertit un résultat brut en tableau bashrow[], une ligne par entrée, colonnes séparées par|. - rc_mysql_nextid
(host, user, password, database, table)— raccourci versrc_mysql_statuspour récupérer le prochainauto_incrementd'une table.
Exemple d'utilisation
# Mise à jour de la table 'users'.
if ! rc_mysql_query "UPDATE" "$dbHostname" "$dbUsername" \
"$dbPassword" "$dbDatabase" \
"UPDATE users SET email='exemple@exemple.fr' WHERE id=1" ; then
echo "La requête MySQL a échoué !"
fi
# Sélection de toutes les lignes de la table 'users'.
rows=$( rc_mysql_query "SELECT" "$dbHostname" \
"$dbUsername" "$dbPassword" \
"$dbDatabase" "SELECT * FROM users ORDER BY id ASC" )
# Conversion du résultat '$rows' en tableau row[].
mysql_fetch_rows "$rows"
# Parcours du tableau row[], découpage de chaque ligne sur le caractère '|'.
for (( i=0; i<${#row[@]}; i++ )); do
id=$( echo ${row[$i]} | cut -d'|' -f1 )
username=$( echo ${row[$i]} | cut -d'|' -f3 )
echo "\$id: $id; \$username: $username"
done
# Récupération du prochain auto_increment de la table 'users'.
nextid=$( rc_mysql_nextid "$dbHostname" "$dbUsername" "$dbPassword" "$dbDatabase" "users" )
Code source
# *********************************************************
# file: mysql.inc.sh
# description: Petite bibliothèque bash pour MySQL.
# auteur original : bibliothèque tierce d'origine (identité non conservée dans cette migration)
# *********************************************************
# Exécute une instruction INSERT|UPDATE|REPLACE|DELETE|DROP et retourne le nombre
# de lignes affectées via ROW_COUNT().
function rc_mysql_query () {
local status=$1
local hostname=${2:-"localhost"}
local username=$3
local password=$4
local database=$5
local query=$6
local error="/tmp/mysql_query.err"
if [ "$status" = "INSERT" -o "$status" = "UPDATE" -o "$status" = "REPLACE" -o "$status" = "DELETE" -o "$status" = "DROP" ]; then
local res=$( mysql --user=$username \
--password=$password \
--database=$database \
--host=$hostname \
--line-numbers --no-beep -Bse "$query; SELECT ROW_COUNT();" 2>$error )
if [ "$( cat $error | wc -l )" -ne 0 ]; then
[ -f "$error" ] && rm -f $error; false
else
[ -f "$error" ] && rm -f $error; true
fi
else
local res=$( mysql --user=$username \
--password=$password \
--database=$database \
--host=$hostname \
--line-numbers --no-beep --column-names -Bse "$query" 2>$error )
if [ "$( cat $error 2>/dev/null | wc -l )" -ne 0 ]; then
if [ -f "$error" ]; then
cat $error; rm -f $error; exit 1
fi
else
echo -e "$res"
fi
fi
}
# Exécute SHOW TABLE STATUS LIKE '<table>' et retourne la valeur d'une clé donnée
# (ex. auto_increment).
function rc_mysql_status () {
local hostname=${1:-"localhost"}
local username=$2
local password=$3
local database=$4
local table=$5
local object=$6
local error="/tmp/mysql_status.err"
local res=$( mysql --user=$username \
--password=$password \
--database=$database \
--host=$hostname \
--column-names --skip-auto-rehash -Be "SHOW TABLE STATUS LIKE '$table'" 2>$error )
if [ "$( cat $error 2>/dev/null | wc -l )" -ne 0 ]; then
if [ -f "$error" ]; then
cat $error; rm -f $error; exit 1
fi
else
echo -e "$res" | \
perl -ne '
BEGIN {
use strict;
use vars qw( $obj @data );
$obj="'$object'";
}
my @tmp = split( /\s+/, $_ );
push( @data, [@tmp] );
END {
my $index=0;
for my $x ( 0 .. ($#data+1) ) {
foreach my $y( 0 .. (@{$data[$x]}+1) ) {
$index = $y if ( lc($data[0][$y]) eq "$obj" );
}
}
print $data[1][$index]."\n";
}'
fi
}
# Convertit le résultat brut MySQL en tableau numérique row[] (tableau 2D simulé,
# colonnes séparées par '|').
function mysql_fetch_rows () {
local data="$*"
array=$( echo -e "$data" | perl -ne '
BEGIN { $i=0; }
next if $_ =~ m/^$/;
$_ = conv_chars( $_ );
$_ =~ s/\t+/\|/g;
print "row[".$i."]=\"".$_."\"\n";
$i++;
sub conv_chars {
my $txt=shift;
$txt =~ s/\cM\n//g;
$txt =~ s/\n\cM//g;
$txt =~ s/\cM//g;
$txt =~ s/\s+$//g;
return $txt;
}
' )
eval $array
}
# Retourne le prochain auto_increment de la table donnée.
function rc_mysql_nextid () {
local hostname=${1:-"localhost"}
local username=$2
local password=$3
local database=$4
local table=$5
rc_mysql_status "$dbHostname" "$dbUsername" "$dbPassword" "$dbDatabase" "$table" "auto_increment"
}
# EOF
Voir aussi
- Mysql config editor — pour éviter le passage du mot de passe en argument de commande
- Mysqldump — outil dédié pour les sauvegardes, à préférer à un script maison pour ce cas d'usage