Advanced Bash Scripting. Joshua Malone (jmalone@ubergeeks.com)



Similar documents
Hands-On UNIX Exercise:

BASH Scripting. A bash script may consist of nothing but a series of command lines, e.g. The following helloworld.sh script simply does an echo.

Unix Shell Scripts. Contents. 1 Introduction. Norman Matloff. July 30, Introduction 1. 2 Invoking Shell Scripts 2

JavaScript: Introduction to Scripting Pearson Education, Inc. All rights reserved.

Unix Scripts and Job Scheduling

HP-UX Essentials and Shell Programming Course Summary

grep, awk and sed three VERY useful command-line utilities Matt Probert, Uni of York grep = global regular expression print

Bash shell programming Part II Control statements

A Crash Course on UNIX

Systems Programming & Scripting

Shell Scripts (1) For example: #!/bin/sh If they do not, the user's current shell will be used. Any Unix command can go in a shell script

Informatica e Sistemi in Tempo Reale

ASCII Encoding. The char Type. Manipulating Characters. Manipulating Characters

PIC 10A. Lecture 7: Graphics II and intro to the if statement

Exercise 1: Python Language Basics

CS Unix Tools & Scripting Lecture 9 Shell Scripting

Member Functions of the istream Class

Basic C Shell. helpdesk@stat.rice.edu. 11th August 2003

PHP Debugging. Draft: March 19, Christopher Vickery

Introduction to Python

AN INTRODUCTION TO UNIX

PHP Tutorial From beginner to master

Introduction to Shell Programming

Sources: On the Web: Slides will be available on:

Eventia Log Parsing Editor 1.0 Administration Guide

Linux Shell Script To Monitor Ftp Server Connection

PYTHON Basics

Introduction to Java Applications Pearson Education, Inc. All rights reserved.

L04 C Shell Scripting - Part 2

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

6. Control Structures

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Exercise 4 Learning Python language fundamentals

Moving from CS 61A Scheme to CS 61B Java

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

Lecture 5: Java Fundamentals III

Command Scripts Running scripts: include and commands

Thirty Useful Unix Commands

VI(Visual) Editor Reference manual

Linux Syslog Messages in IBM Director

Example of a Java program

Introduction to Python

Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T)

Introduction. Chapter 1

6.170 Tutorial 3 - Ruby Basics

So far we have considered only numeric processing, i.e. processing of numeric data represented

MULTIPLE CHOICE. Choose the one alternative that best completes the statement or answers the question.

CPSC 226 Lab Nine Fall 2015

ICS 351: Today's plan

Appendix K Introduction to Microsoft Visual C++ 6.0

ESPResSo Summer School 2012

13 Classes & Objects with Constructors/Destructors

Job Scheduler Daemon Configuration Guide

Object Oriented Software Design

Unix the Bare Minimum

JavaScript: Control Statements I

Lecture 3. Arrays. Name of array. c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] Position number of the element within array c

Lecture 22 The Shell and Shell Scripting

Statements and Control Flow

GDB Tutorial. A Walkthrough with Examples. CMSC Spring Last modified March 22, GDB Tutorial

What is a Loop? Pretest Loops in C++ Types of Loop Testing. Count-controlled loops. Loops can be...

Writing Control Structures

SEO - Access Logs After Excel Fails...

Setting Up the Site Licenses

Lecture 4: Writing shell scripts

JAVA - QUICK GUIDE. Java SE is freely available from the link Download Java. So you download a version based on your operating system.

System Calls and Standard I/O

CPSC 2800 Linux Hands-on Lab #7 on Linux Utilities. Project 7-1

Visual Basic Programming. An Introduction

Keywords are identifiers having predefined meanings in C programming language. The list of keywords used in standard C are : unsigned void

Computer Systems II. Unix system calls. fork( ) wait( ) exit( ) How To Create New Processes? Creating and Executing Processes

Chapter 3. Input and output. 3.1 The System class

IBM Redistribute Big SQL v4.x Storage Paths IBM. Redistribute Big SQL v4.x Storage Paths

MPLAB TM C30 Managed PSV Pointers. Beta support included with MPLAB C30 V3.00

Introduction to Shell Scripting

Learn Perl by Example - Perl Handbook for Beginners - Basics of Perl Scripting Language

Setting Up VNC, SSH Tunnels, and RDP

C++ Input/Output: Streams

An Introduction to the Linux Command Shell For Beginners

Perl in a nutshell. First CGI Script and Perl. Creating a Link to a Script. print Function. Parsing Data 4/27/2009. First CGI Script and Perl

VIP Quick Reference Card

Penetration Testing Ninjitsu 2: Crouching Netcat, Hidden Vulnerabilities. By Ed Skoudis

Visual Logic Instructions and Assignments

Setting up PostgreSQL

Networks. Inter-process Communication. Pipes. Inter-process Communication

1001ICT Introduction To Programming Lecture Notes

COMP 356 Programming Language Structures Notes for Chapter 4 of Concepts of Programming Languages Scanning and Parsing

Chapter One Introduction to Programming

Answers to Even-numbered Exercises

Grid 101. Grid 101. Josh Hegie.

Secure Shell Demon setup under Windows XP / Windows Server 2003

Introduction to Matlab

Transcription:

Advanced Bash Scripting Joshua Malone (jmalone@ubergeeks.com)

Why script in bash? You re probably already using it Great at managing external programs Powerful scripting language Portable and version-stable Almost universally installed

Basic synatx: statements and line format Start the script with #!/path/to/bash like most scripts Beware: /path/to/bash differs between unixes...and even distros of Linux *sigh* No semicolon at the end of a line Semicolons can separate multiple statements on the same line Most statements are either external programs or bash "builtins" See man builtins No parenthesis around function arguments

Basic syntax: variables Variable assignment FOO=BAR No spaces! Variable expansion $FOO ${FOO} Safer way -- brace protected

Basic syntax: conditional evaluation IF statement if <command> then <commands> fi # Command is any process that exists true or false CASE statement case <variable> in <condition1>) <commands> ;; <condition2>) <commands> ;; *) # Default match <commands> ;; esac

More bash syntax While loop while <command> do <commands> done For loop for variable in <list> do <commands> done List is an IFS-separated list of literals or a variable containing one IFS is the "inter-field separator" -- we ll get to this later (usually a space)

External programs It s bash - just type the command :) Capturing output of a command FOO= prog Backticks are more portable FOO=$(prog) But parenthesis are easier to read, safer and also nest (more later) Sending output to a command echo $FOO prog Combining the two FOO=$(echo $BAR prog) Background programs are post-fixed with an & just like normal The special variable $! holds the PID of the last background task started

User output Display output using echo builtin or an external program like printf echo "foo" Outputs "foo" with trailing newline echo -n "foo" Outputs "foo" but doesn t send a newline Escape sequences are parsed if the -e option to echo is given echo -e "\tfoo" Outputs "foo" with a tab character in front and a trailing newline

User input Read input from user using read read foo Accepts user input and stores it into variable foo read -p "<string>" foo Displays the prompt <string> and reads user input into foo read -t 30 foo Read input into foo but time out after 30 seconds read -s foo Read input into foo but don t echo it to the terminal

Tests Remember that if just tests the return value (true/false) of a command. All tests are implemented in external binaries, especially the test or [ program Types of tests string (-z, =,!=,...) integer (-eq, -gt, -lt,...) file (-f, -d, -w,...) Basic Syntax if [ $FOO = $BAR ] if [ $count -lt 5 ] See man test for more tests.

Basic math in bash Bash has basic built-in INTEGER math evaluation using $(( <expression> )) Examples: echo $(( 4 + 5 )) -> "9" FOO=4 echo $(( $FOO + 5 )) -> "9" BAR=$(( 10 / 4 )) echo $BAR -> "2" Remember - integer math For more complex math, or floating point, you ll need to use and external calculator like bc.

Command line arguments to scripts The special variables $1, $2, etc., hold the arguments given on the command line $0 the name of the script as excuted by the shell $# the number of arguments passed to the script $* is an IFS-separated list of all command line arguments $@ is a list of all command line arguments individually double-quoted The built-in command shift moves the CLA s down (to the left) one and discards $1 ($2 becomes $1, $3 becomes $2, etc.) This can be used to iterate over the list or handle optional arguments The external program getopt is also useful for processing a large number of arguments

Functions in bash Declare function by placing parenthesis after the function name Place function commands inside curly braces function_name () { } <commands> Arguments to bash functions are accessed just like CLAs using $1, $2, etc.

Calling bash functions To call a function, type it s name like any other command Arguments to bash functions are not put inside parenthesis foo () { } echo "Argument 1 is $1" foo bar -> outputs "Argument 1 is bar"

Shell globbing Bash shell performs character matching against special symbols process called "globbing" * Any character or characters? Any single character [abc] Any 1 of the characters a, b, or c [^abc] Any 1 character other than a, b, or c {a*,b*} Any of the patterns enclosed in braces (matches a* or b*) Invoke bash with -f flag to disable globbing

Breather Okay - that was your 15 minute crash course in bash. Everybody with me? Good - lets get to the fun stuff :)

Advanced variable expansion Other ways to evaluate a variable ${#foo} Number of characters in (length of) foo ${foo:3:5} Characters 3 through 5 of foo ${foo:4} Foo beginning from the fourth character (chars 4 through end) ${foo#string} Foo, but with the shortest match of "STRING" removed from the beginning ${foo%string} Foo, but with the shortest match of "STRING" removed from the end ${foo%%string} Foo, but with largest match of "STRING" removed from the end ${foo##string} Foo, but with largest match of "STRING" removed from the beginning

Advanced variable expansion (cont.) ${foo/bar/baz} Foo, but with first occurance of string "bar" replaced by string "baz" ${foo//bar/baz} Foo, but with all occurances of string "bar" replaced by string "baz"

Test shortcuts You can use the "logical and" operator && as a short "if" statement if [ $1 -eq 0 ] then <do stuff> fi Is equivalent to [ $1 -eq 0 ] && <do stuff>

Dealing with unset variables If a variable hasn t been set to a value, expanding it results in a NULL This is not an error condition! Providing default values for unset variables: ${foo:-bar} If foo is unset, substitute the value "bar" of instead ${foo:-$bar} If foo is unset, substitute the value of variable bar instead ${foo:=bar} If foo is unset, substitute the value bar and set foo=bar

The "eval" command The eval command constructs a statement and then evaluates it Can be used to get variable-variables in bash Example: set variable FOO to last argument passed to script eval "FOO=\$$#" Remember $# is the number of arguments passed to the script

Manipulating the IFS IFS is the inter-field separation character Default IFS is a space (" ") IFS is set like any other variable Example: parsing /etc/passwd line=$(grep $name /etc/passwd) OLDIFS="${IFS}" IFS=: x=0 for i in $line; do eval "field${x}=\"$i\"" x=$(( x+1 )) done IFS="${OLDIFS}" # assuming name already set # always back up IFS before changing echo "Shell for $name is $field6"

Storing functions in a different file Bash can load in the contents of an external file using source command Source command is abbreviated. Example:. ~/shell-library.sh WARNING: if the sourced file is absent your script will abort Protect it with a file test: [ -f $library ] &&. $library

Here documents You can feed a long block of text into a command or variable using a "Here document" Example: function to print out a help message print_help() { cat << EOF Usage: program [-f] <input> <output> -f: some flag input: input file in some format output: output file in some format EOF } The string "EOF" can be any string NOT included in the contents of your Here document.

More Here documents You can feed the contents of a Here doc to any program that accepts input via stdin Example: applying edits to a config file ex - /etc/ssh_config << EOF /# Host */s/# // /# ForwardX11 no/s/#/ / s/x11 no/x11 yes/ a ForwardX11Trusted yes. x EOF This script sends input to the editor ex (vi in colon-mode) Uncomments the default host stanza Enables X11 forwarding Adds X11Trusted forwarding after the ForwardX11 line Result is similar to applying a patch but more resistant to changes in the default file

Example: Advanced xinitrc startup Using the "wait" command, we can start desk accessories after starting the window manager eval $(ssh-agent) xmodmap ~/.xmodmap-winkey if [ -x "$(which xbindkeys)" ]; then xbindkeys & fi wmaker & WMPID=$! ssh-add ~/.ssh/id_dsa The window manager is running already so it can manage the ssh-askpass window wait ${WMPID} This command simply blocks until the PID given exits ssh-add -k After the "wait", the windowmanager has exited and we can clean up

Example: Writing a log file For complex scripts, I like to write a log file that s seperate from stdout s user interaction Using the standard output redirection initlog () { LOGFILE=$1 echo > ${LOGFILE} } log () { echo $* >> ${LOGFILE} } initlog "script.log" log Starting process foo

Example: Running a log window We can expand our logging example by opening a window to show the log to the user initlog "script.log" xterm -e "tail -f ${LOGIFLE}" & LOGWIN=$! log Some messages # When the script is finished kill $LOGWIN

Example: Re-creating useful utils in bash BSD has this great little utility called jot which can print a sequence of numbers [user@host ~]# jot 5 10 10 11 12 13 14 This is espeically useful for creating the list needed for a for loop Since I ve never seen this for any Linux distros, I decided to just re-create it in bash. My version will just print the numbers between $1 and $2 - good enough for me Also be nice if it can zero-pad the numbers

Example: BSD jot in bash usage() { cat << EOF Usage: $0 [-p length] <start> <end> Generates a series of numbers from start to end in interger steps. -p <n>: pad smaller number out to n digits EOF exit 1 }

Example: BSD jot in bash (cont ) padlen=0 if [ "$1" = -p ]; then padlen="$2" shift; shift fi [ -z "$2" ] && usage begin=$1 end=$2 x=$begin while [ $x -le $end ]; do number=$x if [ $padlen -gt 1 ]; then while [ ${#number} -lt $padlen ]; do number="0${number}"; done fi echo -n "$number" [ $x -lt $end ] && echo -n " " x=$(( $x + 1 )) done