Skip to content

Instantly share code, notes, and snippets.

@NetoBuenrostro
Last active April 28, 2018 01:49
Show Gist options
  • Save NetoBuenrostro/10594241 to your computer and use it in GitHub Desktop.
Save NetoBuenrostro/10594241 to your computer and use it in GitHub Desktop.
Bash programming snippets --moved
- 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
    • 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
    • Debugging
      • Debuging a service or script
    • Checking for a lock file:
    • End

Bash Snippets

Check if a file is newer than an amount of time

# 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

Reference

http://wiki.bash-hackers.org/scripting/tutoriallist https://github.com/google/styleguide/#google-style-guides

Best practices

https://google-styleguide.googlecode.com/svn/trunk/shell.xml https://github.com/ymattw/sandbox/blob/master/sh/bash-best-practices.md

Environment variables

$SHLVL Contains current level of subshells created $HISTFILE File containing bash history

First line

#!/bin/bash

or more portable

#!/usr/bin/env bash

Script boilerplate

#!/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:-}"

Other

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.

File descriptors

Close stdout and stderr for the command being executed:

command 1>&- 2>&-
# Run it in the background and additional ``&``
command 1>&- 2>&- &

Closing File Descriptors

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

Restoring IFS

IFS=$' \t\n'

Positional Parameters 1, 2

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 $9, the arguments must be enclosed in brackets, for example, ${10}, ${11}, ${12}.

The special variables $* and $@ denote all the positional parameters.

  • $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 word

    note:
    "$*" 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.

Check for root

Legacy way

if [ "$(id -u)" != "0" ]; then
   echo "Please run the script as root" 1>&2
   exit 1
fi

Using EUID

if [[ $EUID -ne 0 ]]; then
   echo "Please run the script as root" 1>&2
   exit 1
fi

Check for error when running a command

false
if [ $? -ne 0 ]; then
    echo -e "error found"
    exit 1
fi

Bash and operators

$> 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

Checking for existance of (file, directories, symlinks)

There are others not listed in here

Check for a file existence

if [ -e "file.txt"]; then
    echo "file exist"
fi

Check for a directory existence

if [ -d "directory"]; then
    echo "file exist"
fi

Check for a symlink existence

-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

Read file

Read with while

Single line

while read line; do [COMMAND]; done < [INPUT_FILE]

Example:

while read line; do echo "$line"; done < file.txt

Script

#!/bin/bash
FILE=$1
while read line; do
     echo "This is a line : $line"
done < $FILE

List available variables in a script

compgen -v

Reading parameters from the command line

Check if parameters/options were passed

if [ $# == 0 ] ; then
    echo $message_options_needed
    exit 1;
fi

File system example

In linux you can find another example in this path

/usr/share/doc/util-linux/examples/getopt-parse.bash

Script example

#!/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"

getops

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

Bash backup filename

Year/Month/Day folder

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"

Date in the filename including time

The file will have be similar to 20140801-1532-db.bak

FILENAME="$(date +%Y%m%d-%H%M)-db.bak"

Arrays in bash

To declare an array in bash

array=( one two three )
files=( "/etc/passwd" "/etc/group" "/etc/hosts" )
limits=( 10, 20, 26, 39, 48)

To print an array use:

printf "%s\n" "${array[@]}"
printf "%s\n" "${files[@]}"
printf "%s\n" "${limits[@]}"

iterating an array

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

Concatenate a bash array

a=( one two three )
IFS=","
echo "${a[*]}"

Comparisons

String comparison

if [ "$1" = "$2" ]; then
    echo "The parameters are equal"
fi

Check if the script is run by bash

#!/usr/bin/env bsh

if [ ! -n "$BASH" ]; then
  echo "Please run this script $0 with bash";
  exit 1;
fi

shebang, hashbang

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

get the current shell

echo "$(readlink -f /proc/$$/exe)";

test if running interactively

#If not running interactively, don't do anything
[ -z "$PS1" ] && return

using if block

if [ -z "$PS1" ]; then
    exit
fi

Parameter expansion

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

Parameter Expansion

Title : Welcome Author : You Logo : True

[TITLE]

Madoko

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. If parameter is unset or null, the expansion of word (or an empty string if word is omitted) shall be substituted; otherwise, the value of parameter shall be substituted.
  • ${parameter:=[word]} : Assign Default Values. If parameter is unset or null, the expansion of word (or an empty string if word is omitted) shall be assigned to parameter. In all cases, the final value of parameter shall be substituted. Only variables, not positional parameters or special parameters, can be assigned in this way.
  • ${parameter:?[word]} : Indicate Error if Null or Unset. If parameter is unset or null, the expansion of word (or a message indicating it is unset if word is omitted) shall be written to standard error and the shell exits with a non-zero exit status. Otherwise, the value of parameter shall be substituted. An interactive shell need not exit.
  • ${parameter:+[word]} : Use Alternative Value. If parameter is unset or null, null shall be substituted; otherwise, the expansion of word (or an empty string if word 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.
The following four varieties of parameter expansion provide for substring processing. In each case, pattern matching notation (see [Pattern Matching Notation](#tag_18_13)), rather than regular expression notation, shall be used to evaluate the patterns. 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. Enclosing the full parameter expansion string in double-quotes shall not cause the following four varieties of pattern characters to be quoted, whereas quoting characters within the braces shall have this effect. In each variety, if _word_ is omitted, the empty pattern shall be used.
${_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.
##### Examples
  • ${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 if x 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.

console lines cols [columns, lines, number]

  • tput cols tells you the number of columns.
  • tput lines tells you the number of rows.
echo $(tput cols)x$(tput lines)

Script to get all the PPA installed on a system

#! /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

Built-in's

Job Control Builtins

http://www.gnu.org/software/bash/manual/bashref.html#Job-Control-Builtins

  • wait

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 comments

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

Running commands [a]synchronously

#!/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

Output database description in xml format

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

extract mysql DB as DIA diagrams using xslt

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

Variables

Check if variable is set

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

Assigning

Multi-line using read

read -d '' a <<eoc
This
is
a multiline
value
eoc
Test
echo "$a"

#-- output
# This
# is
# a multiline
# value

Multiline using cat

a=$(cat <<eoc
This
is
a multiline
value
eoc
)
Test
echo "$a"

# -- output
# This
# is
# a multiline
# value

Debugging

Debuging a service or script

sudo sh -x /etc/init.d/varnish start

Checking for a lock file:

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

End

#!/bin/bash -
#===============================================================================
#
# FILE: <file name>
#
# USAGE: ./<filename>
#
# DESCRIPTION:
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# AUTHOR: Ernesto Buenrostro ([email protected])
# ORGANIZATION:
# CREATED: <date>
# REVISION: ---
#===============================================================================
# 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
#--- FUNCTION ----------------------------------------------------------------
# NAME: <FUNCTION NAME>
# DESCRIPTION: ---
# PARAMETERS: ---
# RETURNS: ---
#-------------------------------------------------------------------------------
#--- END FUNCTION <FUNCTION NAME> ----------------------------------------------------------------
# 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:-}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment