Professional Documents
Culture Documents
apropos searches manpage names and descriptions for regular expressions supplied
as arguments. POLVORA|!!!!!!!!!!!!!!!!!!!!!!!!!!!!!s
locate and slocate consult database files about the system (usually compiled and
updated by a cron job) to find files or commands almost instantly.
Enclose a string in single quotes unless it contains elements that you want the
shell
to interpolate.
type command shows you what commands are.
bash --version
chsh -s command to change your default shell.
Add/Remove Programs
tools, the terminal-based aptitude tool, or from the command line:
apt-get update && apt-get install bash bash3 bash-builtins bash-doc bash3-doc
For Red Hat distributions, including Fedora Core (FC) and Red Hat Enterprise
Linux (RHEL), use the GUI Add/Remove Applications tool (if the GUI is missing
from the menus, at a command line for RHEL3 type redhat-config-packages & or for
RHEL4 type system-config-packages &). For a command line only:
up2date install bash
Getting bash for Windows
use Cygwin
http://www.cygwin.com/setup.exe
User Guide at http://cygwin.com/cygwin-ug-net/
set -o noclobber -> command that tels shell to not override files
##################
# Standard INPUT #
##################
#read from prompt
read -p "$prompt" answer
or
read -s -p "password: " PASSWD ; printf "%b" "\n"
#using bash to select from a list of options
Use bash s built-in select construct to generate a menu
#prompt password without being echoed
read -s -p "password: " PASSWD
The -s option tells the read command not to echo the characters typed
and thus may be accessed via a core dump or /proc/core.
#Telling if a command succeded or not
The shell variable $? will be set with a non-zero value if the command fails
You can run a command in the background by putting an ampersand (&)
"fg %1" - recover to foreground
"kill %1" - kill first job
If you start a job and then realize it will take longer to complete than you tho
ught,
you can pause it using Ctrl-Z, which will return you to a prompt. You can then t
ype
bg to un-pause the job so it will continue running in the background.
Arrays are easy to initialize if you know the values as you write the script. Th
e format
is simple:
MYRA=(first second third home)
Each element of the array is a separate word in the list enclosed in parentheses
. Then
you can refer to each this way:
echo runners on ${MYRA[0]} and ${MYRA[2]}
Pg. 131
# bash arithmetic
test if file is readable and writable
if [ -r $FILE -a -w $FILE ]
Here s an example of a more complex test with the parentheses properly escaped for
multiple statements:
if [ -r "$FN" -a \( -f "$FN" -o -p "$FN" \) ]
#Looping with count
for (( i=0 ; i < 10 ; i++ )) ; do echo $i ; done
The use of double parentheses is meant to indicate that these are arithmetic exp
ressions.
for (( i=0, j=0 ; i+j < 10 ; i++, j++ ))
do
echo $((i*j))
done
#Looping with Floating-Point Values
Use the seq command to generate your floating-point values,
#You have a simple SQL script that you would like to run against different datab
ases
to reset them for tests that you want to run.
#!/usr/bin/env bash
# cookbook filename: dbinit.1
#
DBLIST=$(sh ./listdb | tail +2)
select DB in $DBLIST
do
echo Initializing database: $DB
mysql -uuser -p $DB <myinit.sql
done
############################
#Intermediate Shell Tools I#
############################
The grep program searches for strings,
the sed program provides a way to edit text as it passes through a pipeline,
and
awk, well, awk is its own interesting beast, a precursor
to perl and a bit of a chameleon it can look quite different depending on how it
is used.
echo * -> ls
Pag. 170
removing files and ask first
rm -i $(grep -l 'This file is obsolete' * )
# Regular expression
$ matches the end of a line
^ matches the begining of a line
hence ^$ matches an empty line
(*) means to repeat zero or more occurrences of the previous character
So A* means zero or more A characters, and
.* means zero or more characters of
\ any special character should be preceeded by backslash
A set of characters enclosed in square brackets (e.g., [abc]) matches any one of
those
characters (e.g., a or b or c ).
\{n,m\}where n is the minimum number of repetitions and m is the maximum. If it
is written as \{n\} it means exactly n times, and when written as \{n,\} then at leas
t n times.
The -exec is a bit odd. Any filename making it this far will become part of a co
mmand
that is executed. The remainder of the lineup to the \; is the command to be
executed. The {} is replaced by the name of the file that was found.
or
locate P1100087.JPG PC220010.JPG PA310075.JPG PA310076.JPG | xargs -i cp '{}' .
find some_directory -type f -print0 | xargs -0 chmod 0644
#Finding Files Across Symbolic Links
find . -follow -name '*.mp3' -print0 | xargs -i -0 mv '{}' ~/songs
# Finding files by date
find . -name '*.jpg' -mtime +90 -print
-mtime predicate takes an argument to specify the timeframe for the search. The
90 stands for 90 days. By using a plus sign on the number (+90) we indicate that
we re
looking for a file modified more than 90 days ago. Write -90 (using a minus sign
) for
less than 90 days. Use neither a plus nor minus to mean exactly 90 days.
###################################
#Additional Features for Scripting#
###################################
To do this properly you need to be able to detach your script from its controlli
ng
tty, that is from the terminal session used to start the daemon. Simply putting
an ampersand on the command isn t enough.
nohup mydaemonscript 0<&- 1>/dev/null 2>&1 &
or:
nohup mydaemonscript >>/var/log/myadmin.log 2>&1 <&- &
#Reusing Code with Includes and Sourcing
include $HOME/myprefs.cfg
#Using Configuration Files in a Script
#Traping interrupts
Use the trap utility to set signal handlers. First, use trap -l (or kill -l) to
list the signals
you may trap. They vary from system to system:
# NetBSD
# Linux
$ trap -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 33) SIGRTMIN 34) SIGRTMIN+1
35) SIGRTMIN+2 36) SIGRTMIN+3 37) SIGRTMIN+4 38) SIGRTMIN+5
39) SIGRTMIN+6 40) SIGRTMIN+7 41) SIGRTMIN+8 42) SIGRTMIN+9
43) SIGRTMIN+10 44) SIGRTMIN+11 45) SIGRTMIN+12 46) SIGRTMIN+13
47) SIGRTMIN+14 48) SIGRTMIN+15 49) SIGRTMAX-15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
trap '' ABRT EXIT HUP INT TERM QUIT, this script would be rather
hard to kill because any of those signals would just be ignored.
$ cat hard_to_kill
#!/bin/bash -
trap ' echo "You got me! $?" ' ABRT EXIT HUP INT TERM QUIT
trap ' echo "Later... $?"; exit ' USR1
sleep 120
$ ./hard_to_kill
^CYou got me! 130
You got me! 130
$ ./hard_to_kill &
[1] 26354
$ kill -USR1 %1
User defined signal 1
Later... 158
You got me! 0
[1]+ Done ./hard_to_kill
$ ./hard_to_kill &
[1] 28180
$ kill %1
You got me! 0
[1]+ Terminated ./hard_to_kill
date +'%Y-%m-%d'
cal 1 2017
###########################
#Parsing and Similar Tasks#
###########################
getopts program
#!/usr/bin/env bash
# cookbook filename: getopts_example
#
# using getopts
#
aflag=
bflag=
while getopts 'ab:' OPTION
do
case $OPTION in
a) aflag=1
;;
b) bflag=1
bval="$OPTARG"
;;
?) printf "Usage: %s: [-a] [-b value] args\n" $(basename $0) >&2
exit 2
;;
esac
done
shift $(($OPTIND 1))
if [ "$aflag" ]
then
printf "Option -a specified\n"
fi
if [ "$bflag" ]
then
printf 'Option -b "%s" specified\n' "$bval"
fi
printf "Remaining arguments are: %s\n" "$*"
P. 272
#getopts
The getopts built-in will set the variable named in the second argument to the v
alue
that it finds when it parses the shell script s argument list ($1, $2, etc).
If you just want getopts to be quiet and not report any errors at all, just assi
gn
$OPTERR=0 before you begin parsing
But if you want getopts to give you more information
without the error messages, then just begin the option list with a colon.
shift statement used to move the positional parameters of the shell script
from $1, $2, etc.
##Parsing some HTML
cat $1 | sed -e 's/>/>/g' | grep '<a' | while IFS='"' read a b c ; do echo $b; d
one
(that s g r e p . * ). The single quotes tell the shell to take the inner characters
literally
and not do any shell expansion on them;
hexdump -C outfile
p. 303
##############################
#Writing Secure Shell Scripts#
##############################
Security by obscurity will never work for long, though some forms of it can be a
useful
additional layer of security. For example, having daemons assigned to listen on
nonstandard port numbers will keep a lot of the so-called script-kiddies away. B
ut
security by obscurity must never be the only layer of security because sooner or
later,
someone is going to discover whatever you ve hidden.
As Bruce Schneier says, security is a process. It s not a product, object, or tech
nique,
and it is never finished. As technology, networks, attacks and defenses evolve,
so
must your security process. So what does it mean to write secure shell scripts?
Use the bash built-in umask to set a known good state at the beginning of every
script:
nice_long_random_string=$( (last ; who ; netstat -a ; free ; date \
; echo $RANDOM) | md5sum | cut -d' ' -f1 )
/dev/urandom is not allways an available resource. $RANDOM is more ubiquous choi
ce to assure random keys
Using the setuid or setgid bit on a shell script will create more problems especia
lly
security problems than it solves. Some systems (such as Linux) don t even honor
the setuid bit on shell scripts, so creating setuid shell scripts creates an unn
ecessary
portability problem in addition to the security risks.
restrictions go into effect after the user s .bash_profile and environment files a
re
run. In addition, it is wise to change the owner of the users .bash_profile and .
bashrc
to root, and make these files read-only.
This means that the restricted shell user s entire environment is set up in /etc/p
rofile
and .bash_profile.
Since the user can t access /etc/profile and can t overwrite .bash_
profile, this lets the system administrator configure the environment as he sees
fit.
"""""""""""""""""""""""""""""""""""
To actually use the keychain-wrapped ssh-agent from a script or cron, simply sou
rce
the file keychain creates from your script. keychain can also handle GPG keys:
[ -r ~/.ssh-agent ] && source ~/.ssh-agent \
|| { echo "keychain not runnin" >&2 ; exit 1; }
#FIND IP ADDRESS
#ipv4
/sbin/ifconfig -a | awk '/(cast)/ { print $2 }' | cut -d':' -f2 | head -1
#ipv6
/sbin/ifconfig -a | egrep 'inet6 addr:|address:' | cut -d':' -f2- | cut -d'/' -f
1
| head -1 | tr -d ' '
#external ip
wget -qO - http://www.ippages.com/simple/
The first way to send mail from your script is to write some code to generate an
d
send a message, as follows:
# Simple
cat email_body | mail -s "Message subject" recipient1@example.com recipient2@exa
mple.
com
or:
# Attachment only
$ uuencode /path/to/attachment_file attachment_name | mail -s "Message Subject"
recipient1@example.com recipient2@example.com
or:
# Attachment and body
$ (cat email_body ; uuencode /path/to/attachment_file attachment_name) | mail -s
"Message Subject" recipient1@example.com recipient2@example.com
$PS1 and $PS1 are regex environment variables which specify the look of the shel
l prompt
export PS1='ientifiableREGEX'
export PS1='\n[\u@\h jobs:\j]\n$PWD\$ '
#Having datetime history
export HISTTIMEFORMAT='%Y-%m-%d_%H:%M:%S; '
Sample bashrc (we know this is long, but read it for ideas):
PGINA 426
###Housekeeping and Administrative Tasks
info bash | less
###Embedding Documentation in Shell Scripts
Unzipping many zip files
You could also use a loop to unzip each file:
for x in /path/to/date*/name/*.zip; do unzip "$x"; done
or:
for x in $(ls /path/to/date*/name/*.zip 2>/dev/null); do unzip $x; done
####Recovering Disconnected Sessions Using screen
To exit out of screen and your session, keep typing exit until all the sessions
are
gone. You can also type Ctrl-A Ctrl-\ or Ctrl-A :quit to exit screen itself (ass
uming
you haven t changed the default meta-key of Ctrl-A yet).
###############################
#Working faster by typing less#
###############################
##############################
#Tips and Traps: Common Goofs#
#for Novices 20 #
##############################
#Deleting files using empty variables
Never do:
rm -rf $files_to_delete
Never, ever, ever do:
rm -rf /$files_to_delete
Use this instead:
[ "$files_to_delete" ] && rm -rf $files_to_delete