- Bash Snippets
- Check if a file is newer than an amount of time
- Reference
- Best practices
- Environment variables
- First line
- Script boilerplate
- Other
- [Special Variables][3]
- File descriptors
- Closing File Descriptors
- Restoring IFS
- [Positional Parameters][1, 2]
- Check for root
- Legacy way
- Using EUID
- Check for error when running a command
- Bash and operators
- Checking for existance of \(file, directories, symlinks\)
- Check for a file existence
- Check for a directory existence
- Check for a symlink existence
- Read file
- Read with ``while``
- Single line
- Script
- List available variables in a script
- Reading parameters from the command line
- Check if parameters/options were passed
- File system example
- Script example
- [Bash comparison][4]
- Bash backup filename
- Year/Month/Day folder
- Date in the filename including time
- Arrays in bash
- To declare an array in bash
- To print an array use:
- iterating an ``array``
- Concatenate a bash array
- Comparisons
- String comparison
- Check if the script is run by bash
- !/usr/bin/env bsh
- shebang, hashbang
- get the current shell
- test if running interactively
- using if block
- Parameter expansion - Parameter Expansion
- Madoko
- Examples
- [console lines cols][columns, lines, number]
- Script to get all the PPA installed on a system
- Built-in's
- Job Control Builtins
- wait
- Job Control Builtins
- Bash comments
- Running commands [a]synchronously
- Output database description in xml format
- extract mysql DB as DIA diagrams using xslt
- Variables
- Check if variable is set
- Assigning
- Multi-line using read
- Test
- Multiline using cat
- Test
- Multi-line using read
- Assigning
- Debugging
- Debuging a service or script
- Checking for a lock file:
- End
# Check if it is newer than 10 days
if [[ $(find "$filename" -mtime -10 -print) ]]; then
echo "File $filename exists and is older than 100 days"
fi
http://wiki.bash-hackers.org/scripting/tutoriallist https://github.com/google/styleguide/#google-style-guides
https://google-styleguide.googlecode.com/svn/trunk/shell.xml https://github.com/ymattw/sandbox/blob/master/sh/bash-best-practices.md
$SHLVL
Contains current level of subshells created
$HISTFILE
File containing bash history
#!/bin/bash
or more portable
#!/usr/bin/env bash
#!/usr/bin/env bash
# Exit on error. Append ||true if you expect an error.
# set -e is safer than #!/bin/bash -e because that is neutralised if
# someone runs your script like `bash yourscript.sh`
set -o errexit
# Bash will remember & return the highest exitcode in a chain of pipes.
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`
set -o pipefail
set -o nounset
# set -o xtrace
# Set magic variables for current file & dir
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "${__dir}")" && pwd)" # <-- change this
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
arg1="${1:-}"
https://github.com/kvz/bash3boilerplate/blob/master/main.sh
Special Variables3
Character Definition
$* Expands to the positional parameters, starting from one. When the
expansion occurs within double quotes, it expands to a single word
with the value of each parameter separated by the first character of
the IFS special variable.
$@ Expands to the positional parameters, starting from one. When the
expansion occurs within double quotes, each parameter expands to a
separate word.
$# Expands to the number of positional parameters in decimal.
$? Expands to the exit status of the most recently executed foreground
pipeline.
$- A hyphen expands to the current option flags as specified upon
invocation, by the set built-in command, or those set by the shell
itself (such as the -i).
$$ Expands to the process ID of the shell.
$! Expands to the process ID of the most recently executed background
(asynchronous) command.
$0 Expands to the name of the shell or shell script.
$_ The underscore variable is set at shell startup and contains the
absolute file name of the shell or script being executed as passed
in the argument list. Subsequently, it expands to the last argument
to the previous command, after expansion. It is also set to the full
pathname of each command executed and placed in the environment
exported to that command. When checking mail, this parameter holds
the name of the mail file.
Close stdout and stderr for the command being executed:
command 1>&- 2>&-
# Run it in the background and additional ``&``
command 1>&- 2>&- &
exec 0>&- # close stdin
exec 1>&- # close stdout
exec 2>&- # close stderr
Example:
#!/bin/bash
##
## Shell Daemon For: Backup /root/
## (poorly coded, quick and dirty, example)
##
PIDFILE="/var/run/rootmirror.pid"
LOGFILE="/log/log/rootmirror-%Y-%m-%d.log"
NOHUP="/usr/bin/nohup"
CRONOLOG="/usr/bin/cronolog"
case $1 in
start)
exec 0>&- # close stdin
exec 1>&- # close stdout
exec 2>&- # close stderr
$NOHUP $0 run | $CRONOLOG $LOGFILE >> /dev/null &
;;
stop)
/bin/kill $(cat $PIDFILE)
;;
run)
pgrep -f "$0 $1" > $PIDFILE
while [ true ]; do
event=$(inotifywait -q -e close_write --format "%f" /root/)
( cp -v "/root/$event" "/var/lib/rootmirror/$event" )&
done
;;
*)
echo "$0 [ start | stop ]"
exit 0
;;
esac
IFS=$' \t\n'
Arguments passed to the script from the command line: $0, $1, $2, $3 . . .
$0 is the name of the script itself, $1 is the first argument, $2 the second, $3 the third, and so forth. After
The special variables
-
$0, $1, $2, etc.
Positional parameters, passed from command line to script, passed to a function, or set to a variable -
$#
Number of command-line arguments or positional parameters -
$*
All of the positional parameters, seen as a single wordnote:
"$*"
must be quoted. -
$@
Same as$*
, but each parameter is a quoted string, that is, the parameters are passed on intact, without interpretation or expansion. This means, among other things, that each parameter in the argument list is seen as a separate word.note:
"$@"
should be quoted.
if [ "$(id -u)" != "0" ]; then
echo "Please run the script as root" 1>&2
exit 1
fi
if [[ $EUID -ne 0 ]]; then
echo "Please run the script as root" 1>&2
exit 1
fi
false
if [ $? -ne 0 ]; then
echo -e "error found"
exit 1
fi
$> true || echo 'fail' # this don't execute the second part
$> false || echo 'fail' # if the first fail then the second get's executed
$> true && echo 'succeed' # the first succeed then this execute the second part
$> false && echo 'succeed' # if the first fail then the second doesn't get's executed
$> false ; echo 'succeed' # Both are executed always
There are others not listed in here
if [ -e "file.txt"]; then
echo "file exist"
fi
if [ -d "directory"]; then
echo "file exist"
fi
-L check if the symlinked file exists -h check for the symlink exists (the file may not exists)
if [ -L "directory"]; then
echo "file exist"
fi
while read line; do [COMMAND]; done < [INPUT_FILE]
Example:
while read line; do echo "$line"; done < file.txt
#!/bin/bash
FILE=$1
while read line; do
echo "This is a line : $line"
done < $FILE
compgen -v
if [ $# == 0 ] ; then
echo $message_options_needed
exit 1;
fi
In linux you can find another example in this path
/usr/share/doc/util-linux/examples/getopt-parse.bash
#!/bin/bash
# Get the program/script name
PROGNAME=`basename $0`
# Check if GNU enhanced getopt is available
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# ":" added after the option means it needs a parameter
# "::" added after the option means it is an optional parameter, if used (not recomended) the option should be passed like -aOptionalParameter and not like -a OptionalParameter is better to use in long options like --all=OptionalParameters
# <http://stackoverflow.com/questions/26431682/why-cant-i-have-a-space-between-option-and-optional-argument-using-getopt#answer-26432578>
ARGS=`getopt -q --name "$PROGNAME" --long help,output:,verbose --options ho:v -- "$@"`
else
# Original getopt is available (no long option names, no whitespace, no sorting)
ARGS=`getopt ho:v "$@"`
fi
# check if passing any parameter otherwise fail
if [ $? != 0 ]; then
echo "$PROGNAME: usage error (use -h for help)" >&2
while true ; do
case "$1" in
-h | --help | -o | --output | -v | --verbose | --) break ;;
# Giving a hint of what may be wrong
--hlep | hepl) echo "$1 is invalid. Did you mean --help?" >&2 ; break ;;
# Otherwise the parameter is invalid
*) echo "Invalid parameter '$1'" >&2 ;;
esac
shift
done
exit 2
fi
# if the script needs at least one parameter
if [ $# -eq 0 ]; then
echo "$PROGNAME: usage error (use -h for help)" >&2
exit 2
fi
# Options processing
eval set -- "$ARGS"
while true ; do
case "$1" in
-h | --help) HELP=yes;;
# We need to shift so we remove the option parameter
-o | --output) OUTFILE="$2"; shift ;;
-v | --verbose) VERBOSE=yes ;;
--) shift ; break ;;
*) echo "Internal error!" >> $PROGNAME 2>&1; exit 1 ;;
esac
shift
done
# Remaining parameters can be processed
if [ $# -gt 0 ]; then
for ARG in "$@"; do
echo "$PROGNAME: argument: $ARG"
done
fi
echo "$PROGNAME: verbose: $VERBOSE"
echo "$PROGNAME: output: $OUTFILE"
echo "$PROGNAME: help: $HELP"
https://www.chromium.org/chromium-os/shell-style-guidelines
#!/bin/sh
die() {
echo "${0##*/}: error: $*" >&2
exit 1
}
usage() {
echo "Usage: foo [options] [args]
This does something useful!
Options:
-o <file> Write output to <file>
-v Run verbosely
-h This help screen"
exit 0
}
main() {
local flag
local verbose="false"
local out="/dev/stdout"
while getopts 'ho:v' flag; do
case ${flag} in
h) usage ;;
o) out="${OPTARG}" ;;
v) verbose="true" ;;
*) die "invalid option found" ;;
esac
done
if [[ ${verbose} == "true" ]]; then
echo "verbose mode is enabled!"
else
echo "will be quiet"
fi
if [[ -z ${out} ]]; then
die "-o flag is missing"
fi
echo "writing output to: '${out}'"
# Now remaining arguments are in "$@".
...
}
main "$@"
Bash comparison4
DAY=`date +%d`
MONTH=`date +%m`
YEAR=`date +%Y`
minute=$(date +%M)
hour=$(date +%H)
# Backup directory to use (2011/08/31 for 08.31.2011)
BKDIR="/backups/$YEAR/$MONTH/$DAY"
if [ ! -d "$BKDIR" ]; then
mkdir -p $BKDIR
fi
BKLOG="/backups/$YEAR/$MONTH/$DAY.log"
The file will have be similar to 20140801-1532-db.bak
FILENAME="$(date +%Y%m%d-%H%M)-db.bak"
- bash array tutorial
- Multi-dimension using associative arrays in bash
- Bash associative array examples
- Arrays
array=( one two three )
files=( "/etc/passwd" "/etc/group" "/etc/hosts" )
limits=( 10, 20, 26, 39, 48)
printf "%s\n" "${array[@]}"
printf "%s\n" "${files[@]}"
printf "%s\n" "${limits[@]}"
for i in "${arrayName[@]}"
do
:
# do whatever on $i
done
Example:
#!/bin/bash
# declare an array called array and define 3 vales
array=( one two three )
for i in "${array[@]}"
do
echo $i
done
a=( one two three )
IFS=","
echo "${a[*]}"
if [ "$1" = "$2" ]; then
echo "The parameters are equal"
fi
#!/usr/bin/env bsh
if [ ! -n "$BASH" ]; then
echo "Please run this script $0 with bash";
exit 1;
fi
Is the first line in a script and it is used by exec and it is who determines which shell to use to run the script
!#/bin/sh
If you want to execute a script using the shebang you must activate the x bit and run it through it like
/home/user/myscript.sh
or you can use
/usr/bin/env /home/user/myscript.sh
echo "$(readlink -f /proc/$$/exe)";
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
if [ -z "$PS1" ]; then
exit
fi
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
Title : Welcome Author : You Logo : True
[TITLE]
The format for parameter expansion is as follows:
${expression}
where expression consists of all characters until the matching '}'. Any '}' escaped by a or within a quoted string, and characters in embedded arithmetic expansions, command substitutions, and variable expansions, shall not be examined in determining the matching '}'.
The simplest form for parameter expansion is:
${parameter}
The value, if any, of parameter shall be substituted.
The parameter name or symbol can be enclosed in braces, which are optional except for positional parameters with more than one digit or when parameter is a name and is followed by a character that could be interpreted as part of the name. The matching closing brace shall be determined by counting brace levels, skipping over enclosed quoted strings, and command substitutions.
If the parameter is not enclosed in braces, and is a name, the expansion shall use the longest valid name (see XBD Name), whether or not the variable represented by that name exists. Otherwise, the parameter is a single-character symbol, and behavior is unspecified if that character is neither a digit nor one of the special parameters (see Special Parameters).
If a parameter expansion occurs inside double-quotes:
-
Pathname expansion shall not be performed on the results of the expansion.
-
Field splitting shall not be performed on the results of the expansion, with the exception of '@'; see Special Parameters.
In addition, a parameter expansion can be modified by using one of the following formats. In each case that a value of word is needed (based on the state of parameter, as described below), word shall be subjected to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. If word is not needed, it shall not be expanded. The '}' character that delimits the following parameter expansion modifications shall be determined as described previously in this section and in Double-Quotes. (For example, ${foo-bar} xyz} would result in the expansion of foo followed by the string xyz} if foo is set, else the string "barxyz}" ).
-
${parameter:-[word]}
: Use Default Values. Ifparameter
isunset
ornull
, the expansion ofword
(or an empty string ifword
is omitted) shall be substituted; otherwise, the value ofparameter
shall be substituted. -
${parameter:=[word]}
: Assign Default Values. Ifparameter
isunset
ornull
, the expansion ofword
(or an empty string ifword
is omitted) shall be assigned toparameter
. In all cases, the final value ofparameter
shall be substituted. Only variables, not positional parameters or special parameters, can be assigned in this way. -
${parameter:?[word]}
: Indicate Error ifNull
orUnset
. Ifparameter
isunset
ornull
, the expansion of word (or a message indicating it isunset
ifword
is omitted) shall be written to standard error and the shell exits with a non-zero exit status. Otherwise, the value ofparameter
shall be substituted. An interactive shell need not exit. -
${parameter:+[word]}
: Use Alternative Value. Ifparameter
isunset
ornull
,null
shall be substituted; otherwise, the expansion ofword
(or an empty string ifword
is omitted) shall be substituted.
In the parameter expansions shown previously, use of the in the format shall result in a test for a parameter that is unset or null; omission of the shall result in a test for a parameter that is only unset. If parameter is '#' and the colon is omitted, the application shall ensure that word is specified (this is necessary to avoid ambiguity with the string length expansion). The following table summarizes the effect of the :
| | parameter Set and Not Null | parameter Set But Null | parameter Unset |
|--------------------|----------------------------|------------------------|-----------------|
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word} | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word | assign word |
| ${parameter=word} | substitute parameter | substitute null | assign word |
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
| ${parameter?word} | substitute parameter | substitute null | error, exit |
| ${parameter:+word} | substitute word | substitute null | substitute null |
| ${parameter+word} | substitute word | substitute word | substitute null |
In all cases shown with "substitute", the expression is replaced with the value shown. In all cases shown with "assign", parameter is assigned that value, which also replaces the expression.
- ${#_parameter_}
- **String Length**. The length in characters of the value of _parameter_ shall be substituted. If _parameter_ is '*' or '@', the result of the expansion is unspecified. If _parameter_ is unset and [_set_](#set) **-u** is in effect, the expansion shall fail.
- ${_parameter_%**[**_word_**]**}
- **Remove Smallest Suffix Pattern**. The _word_ shall be expanded to produce a pattern. The parameter expansion shall then result in _parameter_, with the smallest portion of the suffix matched by the _pattern_ deleted. If present, _word_ shall not begin with an unquoted '%'.
- ${_parameter_%%**[**_word_**]**}
- **Remove Largest Suffix Pattern**. The _word_ shall be expanded to produce a pattern. The parameter expansion shall then result in _parameter_, with the largest portion of the suffix matched by the _pattern_ deleted.
- ${_parameter_#**[**_word_**]**}
- **Remove Smallest Prefix Pattern**. The _word_ shall be expanded to produce a pattern. The parameter expansion shall then result in _parameter_, with the smallest portion of the prefix matched by the _pattern_ deleted. If present, _word_ shall not begin with an unquoted '#'.
- ${_parameter_##**[**_word_**]**}
- **Remove Largest Prefix Pattern**. The _word_ shall be expanded to produce a pattern. The parameter expansion shall then result in _parameter_, with the largest portion of the prefix matched by the _pattern_ deleted.
-
${parameter}
: In this example, the effects of omitting braces are demonstrated.a=1 set 2 echo ${a}b-$ab-${1}0-${10}-$10 # 1b--20--20
-
${parameter:-word}
: In this example,ls
is executed only ifx
is null or unset. (The$(ls)
command substitution notation is explained in Command Substitution.)${x:-$(ls)}
-
${parameter:=word}
:unset X echo ${X:=abc} # abc
-
${parameter:?word}
:unset posix echo ${posix:?} # sh: posix: parameter null or not set
-
${parameter:+word}
:set a b c echo ${3:+posix} # posix
-
${#parameter}
:HOME=/usr/posix echo ${#HOME} # 10
-
${parameter%word}
:x=file.c echo ${x%.c}.o # file.o
-
${parameter%%word}
:x=posix/src/std echo ${x%%/*} # posix
-
${parameter#word}
:x=$HOME/src/cmd echo ${x#$HOME} # /src/cmd
-
${parameter##word}
:x=/one/two/three echo ${x##*/} # three
The double-quoting of patterns is different depending on where the double-quotes are placed:
-
"${x#*}"
: The<asterisk>
is a pattern character. -
${x#"*"}
: The literal<asterisk>
is quoted and not special.
tput cols
tells you the number of columns.tput lines
tells you the number of rows.
echo $(tput cols)x$(tput lines)
#! /bin/sh
for APT in `find /etc/apt/ -name \*.list`; do
grep -Po "(?<=^deb\s).*?(?=#|$)" $APT | while read ENTRY ; do
HOST=`echo $ENTRY | cut -d/ -f3`
USER=`echo $ENTRY | cut -d/ -f4`
PPA=`echo $ENTRY | cut -d/ -f5`
#echo sudo apt-add-repository ppa:$USER/$PPA
if [ "ppa.launchpad.net" = "$HOST" ]; then
echo sudo apt-add-repository ppa:$USER/$PPA
else
echo sudo apt-add-repository \'${ENTRY}\'
fi
done
done
http://www.gnu.org/software/bash/manual/bashref.html#Job-Control-Builtins
- wait
wait [jobspec or pid ...]
Wait until the child process specified by each process ID pid or job specification jobspec exits and return the exit status of the last command waited for. If a job spec is given, all processes in the job are waited for. If no arguments are given, all currently active child processes are waited for, and the return status is zero. If neither jobspec nor pid specifies an active child process of the shell, the return status is 127.
Example:
process1 &
process2 &
process3 &
process4 &
wait
process5 &
process6 &
process7 &
process8 &
wait
For the above example, 4 processes process1 .. process4 would be started in the background, and the shell would wait until those are completed before starting the next set ..
Bash line comments are defined using the #
caracter
#
Multiline comments can be used with the following notation note the space wetween the :
and the '
: '
This is
a multiline comment
'
or
: <<COMMENTBLOCK
echo "This line will not echo."
This is a comment line missing the "#" prefix.
This is another comment line missing the "#" prefix.
&*@!!++=
The above line will cause no error message,
because the Bash interpreter will ignore it.
COMMENTBLOCK
carefull with this one if the comment contains something similar like this ${something}
will execute it
the fix is to
: <<'COMMENTBLOCK'
echo "This line will not echo."
This is a comment line missing the "#" prefix.
This is another comment line missing the "#" prefix.
&*@!!++=
The above line will cause no error message,
because the Bash interpreter will ignore it.
COMMENTBLOCK
#!/bin/bash
myScript=$(cat <<EOS
backup DB
rsync db
import db
EOS
)
sh -b -c "${myScript}" &
: <<'COMMENTS'
synchronize assets at the same time, so they don't get blocked while creating or importing the DB
COMMENTS
rsync assets
#wait until the two jobs end
wait
exit
echo "<?xml version=\"1.0\"?>"; echo "<root>";mysql -rs -D myDB -e "SHOW TABLES;" | while read table;do mysql --xml -A -D eweek -e "DESC $table"|grep -v "<?xml"; done; echo "</root>" > db.xml
sql2dia.xsl
<?xml version='1.0' ?>
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:dia="http://www.lysator.liu.se/~alla/dia/"
version='1.0'
>
<!--
This stylesheet transforms the output of 'desc table *' in mysql+XML
into an un-gzipped xml dia file
-->
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"
/>
<!-- ================ DOCUMENT ROOT ========================================================== -->
<xsl:template match="/">
<dia:diagram>
<xsl:comment>
Generated with sql2dia.xsl
Author: Pierre Lindenbaum PhD.
[email protected]
</xsl:comment>
<dia:diagramdata>
<dia:attribute name="background">
<dia:color val="#aaaaaa"/>
</dia:attribute>
<dia:attribute name="pagebreak">
<dia:color val="#000099"/>
</dia:attribute>
<dia:attribute name="paper">
<dia:composite type="paper">
<dia:attribute name="name">
<dia:string>#A4#</dia:string>
</dia:attribute>
<dia:attribute name="tmargin">
<dia:real val="2.8222000598907471"/>
</dia:attribute>
<dia:attribute name="bmargin">
<dia:real val="2.8222000598907471"/>
</dia:attribute>
<dia:attribute name="lmargin">
<dia:real val="2.8222000598907471"/>
</dia:attribute>
<dia:attribute name="rmargin">
<dia:real val="2.8222000598907471"/>
</dia:attribute>
<dia:attribute name="is_portrait">
<dia:boolean val="true"/>
</dia:attribute>
<dia:attribute name="scaling">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="fitto">
<dia:boolean val="false"/>
</dia:attribute>
</dia:composite>
</dia:attribute>
<dia:attribute name="grid">
<dia:composite type="grid">
<dia:attribute name="width_x">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="width_y">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="visible_x">
<dia:int val="1"/>
</dia:attribute>
<dia:attribute name="visible_y">
<dia:int val="1"/>
</dia:attribute>
<dia:composite type="color"/>
</dia:composite>
</dia:attribute>
<dia:attribute name="color">
<dia:color val="#d8e5e5"/>
</dia:attribute>
<dia:attribute name="guides">
<dia:composite type="guides">
<xsl:for-each select="row">
<dia:composite type="umlattribute">
<dia:attribute name="name">
<dia:string>#<xsl:value-of select="field[@name='Field']"/>#</dia:string>
</dia:attribute>
<dia:attribute name="type">
<dia:string>#<xsl:value-of select="field[@name='Type']"/>#</dia:string>
</dia:attribute>
<dia:attribute name="value">
<dia:string>#<xsl:value-of select="field[@name='Default']"/>#</dia:string>
</dia:attribute>
<dia:attribute name="comment">
<dia:string>#<xsl:value-of select="field[@name='Field']"/>#</dia:string>
</dia:attribute>
<dia:attribute name="visibility">
<dia:enum val="0"/>
</dia:attribute>
<dia:attribute name="abstract">
<dia:boolean val="false"/>
</dia:attribute>
<dia:attribute name="class_scope">
<dia:boolean val="false"/>
</dia:attribute>
</dia:composite>
</xsl:for-each>
</dia:attribute>
<dia:attribute name="operations"/>
<dia:attribute name="template">
<dia:boolean val="false"/>
</dia:attribute>
<dia:attribute name="templates"/>
</dia:object>
</xsl:template>
</xsl:stylesheet>
(echo "<?xml version=\"1.0\"?>"; echo "<root>";mysql -rs -D eweek -e "SHOW TABLES;" | while read table;do mysql --xml -A -D eweek -e "DESC $table"|grep -v "<?xml"; done; echo "</root>")| xsltproc sql2dia.xsl - | gzip -c > ezp.dia
http://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash#answer-13864829
if [ -z ${var+x} ]; then
echo "var is unset";
else
echo "var is set to '$var'";
fi
read -d '' a <<eoc
This
is
a multiline
value
eoc
echo "$a"
#-- output
# This
# is
# a multiline
# value
a=$(cat <<eoc
This
is
a multiline
value
eoc
)
echo "$a"
# -- output
# This
# is
# a multiline
# value
sudo sh -x /etc/init.d/varnish start
if (set -C; : > lock_file) 2> /dev/null
then
: # lock_file didn't exist: no user running the script
else
echo "Another user is already running that script."
exit 65
fi