Bash notes

From Noah.org
Revision as of 06:13, 4 January 2009 by Root (talk | contribs) (→‎Statements)
Jump to navigationJump to search


Turn off bash history for a session

set +o history

Rename a group of files by extension

For example, rename all images from foo.jpg to foo_2.jpg.

This is somewhat more clear:

for filename in *.jpg ; do mv $filename `basename $filename .jpg`_2.jpg; done

This is more "correct" and doesn't require `basename`:

for filename in *.jpg ; do mv $filename ${filename%.jpg}_2.jpg; done

Special Shell Variables

$*
all parameters separated by the first character of $IFS
$@
all parameters quoted
$#
the number of parameters
$?
exit status of last command
$-
option flags set `set` or passed to shell
$$
pid of this shell
$!
pid of last background command
$0
name of the shell or script
$_
arguments of last command

Variable Expansion and Substitution

Bash can do some freaky things with variables. It can do lots of other substitutions. See "Parameter Expansion" in the Bash man page.

  • ${foo#pattern} - deletes the shortest possible match from the left
  • ${foo##pattern} - deletes the longest possible match from the left
  • ${foo%pattern} - deletes the shortest possible match from the right
  • ${foo%%pattern} - deletes the longest possible match from the right
  • ${foo=text} - If $foo exists and is not null then return $foo. If $foo doesn't exist then create it and set value to text.


absolute and relative paths

Convert a relative path to a absolute path. It is stupid that there is not a command to do this. This does not effect the current working directory. This finds the absolute full path to $1:

echo "absolute path: `cd $1; pwd`"

Get the absolute path of the currently running script.

abs_path_here=`echo -n \`pwd\` ;( [ \`dirname \$0\` == '.' ] && echo ) || echo “/\`dirname \$0\`”`

Statements

Loop on filenames in a directory

for foo in *; do {
  echo ${foo}
}; done

Loop on lines in a file

for foo in $(cat data_file.txt); do {
  echo ${foo}
}; done

while loop

This is kind of like `watch`:

while sleep 1; do lsof|grep -i Maildir; done

get yes/no input feedback from user

YES=1
NO=0
INVALID=-1
yesno()
{
    echo -e $1
    VALID_YN=$FALSE
    YN=
    rval=
    echo -e " [y/n] \c"
    read YN
    if [ -z "$YN" ]
    then
        VALID_YN=$FALSE
        rval=$INVALID
    else
        case "$YN" in
            [Yy]*)
                VALID_YN=$TRUE
                rval=$YES
                ;;
            [Nn]*)
                VALID_YN=$TRUE
                rval=$NO
                ;;
            *)
                VALID_YN=$FALSE
                rval=$INVALID
                ;;
        esac
    fi
    if [ $rval -eq $INVALID ]
    then
        echo "Invalid Response..."
    fi
    return $rval
}

check if running as root

if [ `id -u` = "0" ]; then
    echo "You are root."
    exit 0
fi

Variant. Note alternate syntax.

if [ $(id -u) != 0 ]; then 
    echo "You must be root to run this."
    exit 1
fi

check if process is running

Show the pids of all processes with name "openvpn":

ps -C openvpn -o pid=

Show if a process with pid=12345 is running:

kill -0 12345
echo $?

Check if a process with a given command name and pid is still running. For example, check if ssh process is running with pid 12345: "checkpid ssh 12345". Checkpid script:

#!/bin/sh
# example: checkpid ssh 12345
CMD=$1
PID=$2
for QPID in $(ps -C $CMD -o pid=); do
    if [ $QPID = $PID ]; then
        echo "running"
        exit 0
    fi
done
echo "not running"
exit 1