syntax error near unexpected token `done' in bash code - mysql

I am looking for some working shell code for auto restart mysql servers if it is not working. here are some code witch i foound in google search, listen 3306 port, if it is not working, restart. if can not restart, reboot the server.
Can this code work? If not, is anyone can share me a working code? If yes, i met syntax error near unexpected tokendone' in bash code`, how to solve it? thanks.
PORT=`netstat -na|grep "LISTEN"|grep "3306"|awk -F[:" "]+ '{print $5}'`
MYSQLIP=`ifconfig eth0|awk '/inet/{print $2}'|cut -c 6-`
while [ `whoami` == "root" ]
do
if [ "$PORT" == "3306" ];then
echo "mysql is running......"
else
service mysql restart
if [ "$PORT" == "3306" ];then
else
reboot
fi
fi
break
done
Modify code:
PORT=`netstat -na|grep "LISTEN"|grep "3306"|awk -F[:" "]+ '{print $5}'`
MYSQLIP=`ifconfig eth0|awk '/inet/{print $2}'|cut -c 6-`
while [ `whoami` == "root" ]
do
if [ "$PORT" == "3306" ];then
echo "mysql is running......"
else
service mysql restart
if [ "$PORT" == "3306" ];then
:
else
reboot
fi
fi
break
done

Your condition test must execute some sort of code if true.
It looks like you want to reboot if "$PORT" is not "3306".
You should only use break when testing a condition, otherwise the loop will only execute once.
The PORT variable will not update unless you call the code that sets it again after you need it to update.
Also, you don't need to use grep when you are using awk.
#!/bin/bash
callport ()
{
PORT=`netstat -na|awk -F[:" "]+ '/LISTEN/ && /3306/ {print $5}'`
}
MYSQLIP=`ifconfig eth0|awk '/inet/{print $2}'|cut -c 6-`
while [ `whoami` == "root" ]
do
callport
if [ "$PORT" == "3306" ];then
echo "mysql is running......"
break
else
service mysql restart
callport
if [ "$PORT" != "3306" ];then
reboot
fi
fi
done

Related

Inject .sql files in order using a docker-compose

I'm running an MySQL server docker container using a docker-compose YAML file.
Here is how the file looks like:
version: '3.1'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- ./mysql-dump/samples:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: db_example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
In the db service, the volumne is set to ./mysql-dump/samples:/docker-entrypoint-initdb.d this takes .sql files from ./mysql-dump/sample to inject them to the database.
In my case I have two files file2.sql for the sql schema of the database, and file1.sql for the data.
Since the file appear to be injected in order, I get a NO SUCH TABLE ERROR, surely because the schema is injected last (because it's name is file2.sql)
Is there a way to reverse the order of the injection beside changing the names of the files?
If you go through the documentation of mysql Dockerhub it clearly mentioned that it will dump file in alphabetical order.
When a container is started for the first time, a new database with
the specified name will be created and initialized with the provided
configuration variables. Furthermore, it will execute files with
extensions .sh, .sql and .sql.gz that are found in
/docker-entrypoint-initdb.d. Files will be executed in alphabetical
order. You can easily populate your mysql services by mounting a SQL
dump into that directory and provide custom images with contributed
data. SQL files will be imported by default to the database specified
by the MYSQL_DATABASE variable.
You need to replace file name, suppose db.sql and table.sql so it will first dump db.sql then table.sql
Updated:
To reverse the order of MySQL dump, you have to modify the docker file and entry point.
FROM mysql:8
#From mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
ENTRYPOINT:
#!/bin/bash
set -x
set -eo pipefail
shopt -s nullglob
# if command starts with an option, prepend mysqld
if [ "${1:0:1}" = '-' ]; then
set -- mysqld "$#"
fi
# skip setup if they want an option that stops mysqld
wantHelp=
for arg; do
case "$arg" in
-'?'|--help|--print-defaults|-V|--version)
wantHelp=1
break
;;
esac
done
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
# usage: process_init_file FILENAME MYSQLCOMMAND...
# ie: process_init_file foo.sh mysql -uroot
# (process a single initializer file, based on its extension. we define this
# function here, so that initializer scripts (*.sh) can use the same logic,
ls -r
process_init_file() {
local f="$1"; shift
local mysql=( "$#" )
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[#]}" < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[#]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
}
_check_config() {
toRun=( "$#" --verbose --help )
if ! errors="$("${toRun[#]}" 2>&1 >/dev/null)"; then
cat >&2 <<-EOM
ERROR: mysqld failed while attempting to check config
command was: "${toRun[*]}"
$errors
EOM
exit 1
fi
}
# Fetch value from server config
# We use mysqld --verbose --help instead of my_print_defaults because the
# latter only show values present in config files, and not server defaults
_get_config() {
local conf="$1"; shift
"$#" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null \
| awk '$1 == "'"$conf"'" && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
# match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
}
# allow the container to be started with `--user`
if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
_check_config "$#"
DATADIR="$(_get_config 'datadir' "$#")"
mkdir -p "$DATADIR"
chown -R mysql:mysql "$DATADIR"
exec gosu mysql "$BASH_SOURCE" "$#"
fi
if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
# still need to check config, container may have started with --user
_check_config "$#"
# Get config
DATADIR="$(_get_config 'datadir' "$#")"
if [ ! -d "$DATADIR/mysql" ]; then
file_env 'MYSQL_ROOT_PASSWORD'
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
echo >&2 'error: database is uninitialized and password option is not specified '
echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
exit 1
fi
mkdir -p "$DATADIR"
echo 'Initializing database'
"$#" --initialize-insecure
echo 'Database initialized'
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
# https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
echo 'Initializing certificates'
mysql_ssl_rsa_setup --datadir="$DATADIR"
echo 'Certificates initialized'
fi
SOCKET="$(_get_config 'socket' "$#")"
"$#" --skip-networking --socket="${SOCKET}" &
pid="$!"
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
for i in {30..0}; do
if echo 'SELECT 1' | "${mysql[#]}" &> /dev/null; then
break
fi
echo 'MySQL init process in progress...'
sleep 1
done
if [ "$i" = 0 ]; then
echo >&2 'MySQL init process failed.'
exit 1
fi
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
# sed is for https://bugs.mysql.com/bug.php?id=20545
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[#]}" mysql
fi
if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
fi
rootCreate=
# default root to listen for connections from anywhere
file_env 'MYSQL_ROOT_HOST' '%'
if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'#'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
GRANT ALL ON *.* TO 'root'#'${MYSQL_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL
fi
"${mysql[#]}" <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET ##SESSION.SQL_LOG_BIN=0;
ALTER USER 'root'#'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
GRANT ALL ON *.* TO 'root'#'localhost' WITH GRANT OPTION ;
${rootCreate}
DROP DATABASE IF EXISTS test ;
FLUSH PRIVILEGES ;
EOSQL
if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
fi
file_env 'MYSQL_DATABASE'
if [ "$MYSQL_DATABASE" ]; then
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[#]}"
mysql+=( "$MYSQL_DATABASE" )
fi
file_env 'MYSQL_USER'
file_env 'MYSQL_PASSWORD'
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
echo "CREATE USER '$MYSQL_USER'#'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[#]}"
if [ "$MYSQL_DATABASE" ]; then
echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'#'%' ;" | "${mysql[#]}"
fi
echo 'FLUSH PRIVILEGES ;' | "${mysql[#]}"
fi
echo
ls -r /docker-entrypoint-initdb.d/ > /dev/null
for f in $(ls -r /docker-entrypoint-initdb.d/*); do
process_init_file "$f" "${mysql[#]}"
done
if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
"${mysql[#]}" <<-EOSQL
ALTER USER 'root'#'%' PASSWORD EXPIRE;
EOSQL
fi
if ! kill -s TERM "$pid" || ! wait "$pid"; then
echo >&2 'MySQL init process failed.'
exit 1
fi
echo
echo 'MySQL init process done. Ready for start up.'
echo
fi
fi
exec "$#"
If you run the container, You will see the file is in processing reverse order

How to add `--registry-mirror` when starting docker from "Docker quickstart terminal"?

From the docker distribution document: https://github.com/docker/distribution
It says to configure the docker to use the mirror, we should:
Configuring the Docker daemon
You will need to pass the --registry-mirror option to your Docker daemon on startup:
docker --registry-mirror=https://<my-docker-mirror-host> daemon
I'm newbie to docker, and I start docker from mac normal by the provided "Docker Quickstart Termial" app, which actaully invokes a start.sh shell:
#!/bin/bash
VM=default
DOCKER_MACHINE=/usr/local/bin/docker-machine
VBOXMANAGE=/Applications/VirtualBox.app/Contents/MacOS/VBoxManage
BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m'
unset DYLD_LIBRARY_PATH
unset LD_LIBRARY_PATH
clear
if [ ! -f $DOCKER_MACHINE ] || [ ! -f $VBOXMANAGE ]; then
echo "Either VirtualBox or Docker Machine are not installed. Please re-run the Toolbox Installer and try again."
exit 1
fi
$VBOXMANAGE showvminfo $VM &> /dev/null
VM_EXISTS_CODE=$?
if [ $VM_EXISTS_CODE -eq 1 ]; then
echo "Creating Machine $VM..."
$DOCKER_MACHINE rm -f $VM &> /dev/null
rm -rf ~/.docker/machine/machines/$VM
$DOCKER_MACHINE create -d virtualbox --virtualbox-memory 2048 --virtualbox-disk-size 204800 $VM
else
echo "Machine $VM already exists in VirtualBox."
fi
VM_STATUS=$($DOCKER_MACHINE status $VM)
if [ "$VM_STATUS" != "Running" ]; then
echo "Starting machine $VM..."
$DOCKER_MACHINE start $VM
yes | $DOCKER_MACHINE regenerate-certs $VM
fi
echo "Setting environment variables for machine $VM..."
clear
cat << EOF
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
EOF
echo -e "${BLUE}docker${NC} is configured to use the ${GREEN}$VM${NC} machine with IP ${GREEN}$($DOCKER_MACHINE ip $VM)${NC}"
echo "For help getting started, check out the docs at https://docs.docker.com"
echo
eval $($DOCKER_MACHINE env $VM --shell=bash)
USER_SHELL=$(dscl /Search -read /Users/$USER UserShell | awk '{print $2}' | head -n 1)
if [[ $USER_SHELL == *"/bash"* ]] || [[ $USER_SHELL == *"/zsh"* ]] || [[ $USER_SHELL == *"/sh"* ]]; then
$USER_SHELL --login
else
$USER_SHELL
fi
Is it the correct file that I can put my '--registry-mirror' config to it? What should I do?
If you do a docker-machine create --help:
docker-machine create --help
Usage: docker-machine create [OPTIONS] [arg...]
Create a machine.
Run 'docker-machine create --driver name' to include the create flags for that driver in the help text.
Options:
...
--engine-insecure-registry [--engine-insecure-registry option --engine-insecure-registry option] Specify insecure registries to allow with the created en
gine
--engine-registry-mirror [--engine-registry-mirror option --engine-registry-mirror option] Specify registry mirrors to use
So you can modify your script to add one more parameter:
--engine-registry-mirror=...
However, since your 'default' docker-machine probably already exists (do a docker-machine ls), you might need to remove it first (docker-machine rm default: make sure you can easily recreate your images from your local Dockerfiles, and/or that you don't have data container that would need to be saved first)
Open C:\Users\<YourName>\.docker\daemon.json, edit the "registry-mirrors" entry in that file.
{"registry-mirrors":["https://registry.docker-cn.com"],"insecure-registries":[], "debug":true, "experimental": true}

Bash: testing if executed command was succesfull

I have the following script:
if [ `mysql -u root -p < test.sql` ]; then
echo "success"
else
echo "some error"
fi
How can I check in the if if the command went well or there was some sql error?
You don't need the test command, i.e. [ here.
Assuming that mysql produces a non-zero exit code in case of failure and 0 on success, then you can say:
if mysql -u root -p < test.sql; then
echo "success"
else
echo "some error"
fi
Another way this is typically done is with the "&&" and "||" separators. For example:
mysql -u root -p < test.sql && echo "success" || echo "some error"
If the mysql command exits with status 0, then "success" will be printed. If it doesn't, "some error" will be printed.

Using rsnapshot and mysqldump to backup remote mySQL Databases

I am using rsnapshot to backup our remote servers and I need to add MySQL backups.
rsnapshot calls a remote script that dumps the mysql DB's on the server. The problem is, the script does not exclude the information_schema database and therefore it dies )or appears to die and I have a second problem.)
I'm not sure how I would exclude the information_schema DB from this script:
### SETUP MYSQL LOGIN ###
MUSER='USER'
MPASS='PASSWORD'
MHOST="127.0.0.1"
### Set to 1 if you need to see progress while dumping dbs ###
VERBOSE=0
### Set bins path ###
GZIP=/bin/gzip
MYSQL=/usr/bin/mysql
MYSQLDUMP=/usr/bin/mysqldump
RM=/bin/rm
MKDIR=/bin/mkdir
MYSQLADMIN=/usr/bin/mysqladmin
GREP=/bin/grep
### Setup dump directory ###
BAKRSNROOT=/tmp/rsnapshot/mysql
#####################################
### ----[ No Editing below ]------###
#####################################
### Default time format ###
TIME_FORMAT='%H_%M_%S%P'
### Make a backup ###
backup_mysql_rsnapshot(){
local DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
local db="";
[ ! -d $BAKRSNROOT ] && ${MKDIR} -p $BAKRSNROOT
${RM} -f $BAKRSNROOT/* >/dev/null 2>&1
[ $VERBOSE -eq 1 ] && echo "*** Dumping MySQL Database ***"
[ $VERBOSE -eq 1 ] && echo -n "Database> "
for db in $DBS
do
local tTime=$(date +"${TIME_FORMAT}")
local FILE="${BAKRSNROOT}/${db}.${tTime}.gz"
[ $VERBOSE -eq 1 ] && echo -n "$db.."
${MYSQLDUMP} -u ${MUSER} -h ${MHOST} -p${MPASS} $db | ${GZIP} -9 > $FILE
done
[ $VERBOSE -eq 1 ] && echo ""
[ $VERBOSE -eq 1 ] && echo "*** Backup done [ files wrote to $BAKRSNROOT] ***"
}
### Die on demand with message ###
die(){
echo "$#"
exit 999
}
### Make sure bins exists.. else die
verify_bins(){
[ ! -x $GZIP ] && die "File $GZIP does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQL ] && die "File $MYSQL does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQLDUMP ] && die "File $MYSQLDUMP does not exists. Make sure correct path is set in $0."
[ ! -x $RM ] && die "File $RM does not exists. Make sure correct path is set in $0."
[ ! -x $MKDIR ] && die "File $MKDIR does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQLADMIN ] && die "File $MYSQLADMIN does not exists. Make sure correct path is set in $0."
[ ! -x $GREP ] && die "File $GREP does not exists. Make sure correct path is set in $0."
}
### Make sure we can connect to server ... else die
verify_mysql_connection(){
$MYSQLADMIN -u $MUSER -h $MHOST -p$MPASS ping | $GREP 'alive'>/dev/null
[ $? -eq 0 ] || die "Error: Cannot connect to MySQL Server. Make sure username and password are set correctly in $0"
}
### main ####
verify_bins
verify_mysql_connection
backup_mysql_rsnapshot
Look into mysqldump and its --all-databases parameter. Don't reinvent the wheel!
mysqldump does not dump theINFORMATION_SCHEMA database. If you name that database explicitly on the command line,mysqldump silently ignores it.
If you have a version of mysqldump that does really not exclude INFORMATION_SCHEMA and you need all DBs in seperate files, just exclude it from your loop:
for db in $DBS
do
if [ $db -ne "INFORMATION_SCHEMA" ] ; do
YOUR_STUFF()
done
dome
Replace the following line:
local DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
with
local DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases' -s --skip-column-names|grep -vi information_schema)"

Shell and MySQL custom connection success message

How can I print a custom success message if connected to mysql via shell? Instead of displaying mysql error messages.
Something like this
if [ "$mysql_connected" ]; then
echo "connected"
# do mysql stuff
else
echo "connection failed"
fi
Thanks in advance!
Use exit status as shown below:
mysql -uroot -pabc -e"show databases;"
if [ $? -eq 0 ];then
echo "success";
else
echo "failed to connect";
fi