SlideShare a Scribd company logo
1 of 53
Download to read offline
Shell Scripting Craftsmanship
  Ray Smith
  Portland General Electric



 if [ You can't read this easily ]; then
     move up closer
 else
     Don't say I didn't warn you
 fi
Objectives

• Keep you awake until the Opening Keynote

• Philosophical alignment
   • Context of quality


• Define craftsmanship
   • What makes a good quality desk?
   • What are the common elements of good scripts?
• Rule #1: SHELL SCRIPTS MUST WORK
 • High-visibility tasks
 • Unforgiving tasks
 • Repetitive tasks



• Rule #2: SCRIPTS MUST KEEP WORKING
 • Nothing stays the same
 • Plan on it
Quality, craftsmanship, harmony

• Transparency
   • Maintenance without frustration


• Clear communication
   • Effort without agitation


• Scalability
   • Power without intervention
Spiritual Guidance

• The Art of Unix Programming
   • Eric S. Raymond
   • Addison-Wesley


• Resident anthropologist and roving ambassador of the
  open source movement

• Three decades of unwritten, hard-won software
  engineering wisdom from 13 Unix pioneers
Transparency
• Rule of Robustness
   • Robustness is the child of transparency and simplicity


• Rule of Transparency
   • Design for visibility, inspection, and debugging


• Rule of Simplicity
   • Design for simplicity
   • Add complexity only where you must


• Rule of Clarity
   • Clarity is better than cleverness
Clear Explanations

• Be generous with internal documentation
   • Particularly when being clever or ultra-efficient


     # Find all instances of the string
     find . –type f –exec fgrep –i “$mySTRING” 
     /tmp/dummy {} ; 2>/dev/null


• Document dead-ends and surprises
   • Programming methods that were tried and did not work
   • „Obvious‟ data sources that are unreliable
Predictable Layout

•   Consistent layout for all your scripts
    1.   Header block
    2.   Change log
    3.   Independent variables
    4.   Dependent variables
    5.   Functions
    6.   Run-time procedure


•   Take out the guesswork
Predictable Layout
    #!/bin/bash
    #########################################################
    # File              : sample_script.sh
    # Input values      : Database name (optional)
    # Purpose           : Amaze others
    ########################################################
    #=======================================================
    # Independent variables
    #=======================================================
    export BASEDIR=/usr/lbin/orascripts

    #=======================================================
    # Dependent variables
    # Nothing to change below this line
    #=======================================================
    LOGDIR=$BASEDIR/logs
    WORKFILE=$LOGDIR/workfile.lst
Visual Simplicity

• Be kind to yourself and others

• Layouts and formatting

   USE WHITESPACE

          Break up long lines with 
          back-slash
Just like a SQL statement …
select distinct table_name,column_name from all_tab_columns
where column_name like '%AGREE%' or column_name like '%ANN%„
or table_name like '%ANN%„ or table_name like „%STOR%„ order
by table_name,column_name;



SELECT DISTINCT table_name,column_name
FROM   all_tab_columns
WHERE column_name LIKE '%AGREE%'
OR     column_name LIKE '%ANN%„
OR     table_name LIKE '%ANN%'
OR     table_name LIKE '%STOR%'
ORDER BY table_name,column_name;
Emphasize Visual Flow
  for thisHOST in `cat ${HOSTLIST}`; do
  if [ ${#thisHOST} -gt 5 ]; then
  echo "BIG: ${thisHOST} is ${#thisHOST} characters"
  else
  if [ ${#thisHOST} -lt 3 ]; then
  echo "LITTLE: ${thisHOST} is ${#thisHOST} characters"
  fi
  fi
  done

  for thisHOST in `cat ${HOSTLIST}`; do
       if [ ${#thisHOST} -gt 5 ]; then
              echo "BIG: ${thisHOST} name is long"
       else
              if [ ${#thisHOST} -lt 3 ]; then
                      echo "LITTLE: ${thisHOST} name is short"
              fi
       fi
  done
Discoverability

• Make ${VARIABLES} stand out in your code

• Variable naming conventions
   • ALL_CAPS for session variables
   • CamelCase for function names
   • thisVARIABLE for looped variables

• Be internally consistent
      • Adopt a standard and follow it
Outstanding Variables
    for thishost in `cat $hostlist`; do
      if [ $#thishost -gt 5 ]; then
             longmessage
      else
             if [ $#thishost -lt 3 ]; then
                     shortmessage
             fi
      fi
    done

    for thisHOST in `cat ${HOSTLIST}`; do
      if [ ${#thisHOST} -gt 5 ]; then
             LongMessage
      else
             if [ ${#thisHOST} -lt 3 ]; then
                     ShortMessage
             fi
      fi
    done
The Penny Wise Quiz
a. Shorter variable names =
   Less typing =
   Less work

b. Obscure variable names =
   Reduced transparency =
   Poor quality

• Save your cycles for decyphering the logic
   • Not the variable names
Tuning for Transparency

 • Rule of Optimization
    • Prototype before polishing
    • Get it working before you optimize it


 • Rule of Modularity
    • Write simple parts connected by clean interfaces
    • Functions
    • Temporary files
Efficiency

 • Use shell script functions

  function SetPerms770 {
  echo “nSetting permission to 770 for ${thisFILE}”
  chmod 770 ${thisFILE}/*
  }

  > for thisFILE in `cat ${FILELIST}`; do
  >   SetPerms770
  > done


 • Modularize all repeated code statements
Handiest function ever

 • At the beginning of the script
 • At the end of the script
 • Any time execution might end


 function CleanUpFiles {
   [ $LOGFILE ] && rm –f ${LOGFILE}
   [ $SPOOL01 ] && rm –f ${SPOOL01}
 }
# Functions
# -------------------------------------------------------------------
function CopyFiles {
cd $SOURCE_DIR
ls -1 | grep -i $ORACLE_SID       >$WORKFILE
for thisFILE in `cat $WORKFILE`; do
    SOURCE_FILE=$SOURCE_DIR/$thisFILE
    TARGET_FILE=$TARGET_DIR/$thisFILE
    cp –f $SOURCE_FILE $TARGET_FILE
done
rm -f ${WORKFILE}
}

# -------------------------------------------------------------------
# Run-time procedure
# • Modularize all repeated code statements
  -------------------------------------------------------------------
SOURCE_DIR=${GOLD_DIR}/rman
TARGET_DIR=${LIVE_DIR}/rman
    CopyFiles

SOURCE_DIR=${GOLD_DIR}/security
TARGET_DIR=${LIVE_DIR}/security
    CopyFiles
Transparency Zen

• Rule of Diversity
   • Distrust all claims of “one true way”
   • Including your own


• Revisit older scripts
   • Technologies change
   • Techniques change
The Secret to the (Scripting) Universe


Steal
Adapt
Improve
Repeat
Transparency Wrap-up

Maintenance without frustration:

   • Written with maintenance and on-call in mind


   • Provide useful guidance and instructions


   • Reflect visual simplicity and clear layout


Comments or questions
I’m awake
I’m awake
User Communication

• Rule of Silence
   • Nothing surprising to say: say nothing


• Rule of Repair
   • Repair what you can
   • When you must fail, fail noisily and as soon as possible


• Rule of Least Surprise
   • In interface design, do the least surprising thing
   • Do the most expected thing
Work with the user

• Verify scripted actions

         echo “These files will be backed up:”
         cat ${FILELIST}


• Keep the user informed
   • Share status and decisions

         echo “You asked to delete everything in /etc”

         read -p "Is this correct? [Y|N]" myVal
         case $myVal in . . .
Opatch is a gem
  Running prerequisite checks...

  OPatch detected non-cluster Oracle Home from the inventory
  and will patch the local system only.

  Please shutdown Oracle instances running out of this
  ORACLE_HOME on the local system.
  (Oracle Home = '/cisp_orabase/product/10.2.0')

  Is the local system ready for patching? [y|n]

  User Responded with: Y

  Applying patch 7155252...

  ApplySession applying interim patch '7155252' to OH
  '/cisp_orabase/product/10.2.0'
  Backing up files affected by the patch '7155252' for
  rollback. This might take a while...
Graciousness

• Handle errors with grace
   • Explain the situation
   • Lead the user to a solution



     if [ ${#1} -eq 0 ];then
        echo "The required value for database name"
        echo "was not passed in the command line"
        read -p "Enter the database name: " myVal
        export thisSID=$myVal
     fi
Communicating Failure
• Cryptic feedback is not welcome nor helpful
          >
          > FATAL ERROR: bckpinit_strt error 12
          >
• Terminal output is free, use it if you need it

          >
          > File not found: bckpinit_strt.conf
          >
          > Corrective action required:
          >    Verify bckpinit_strt.conf exists at ABC
          >    and readable by user xyz

          > Email notification has been sent
Signs of Life

• Same script should work in cron or interactive
   • Test for tty (terminal id)




        if tty –s
        then
           echo “Oh good, this is interactive”
           echo “Hello $USER”
        else
           date +“Script $0 started %T” >> $LOGFILE
        fi
Artist and Psychologist

• Break the output into usable blocks
   • Use n and t liberally
       • If it makes it easier for user to understand


• Particularly important for interactive scripts
   • Push the „read‟ statement into their attention
   • “Is the local system ready for patching? [y|n]”


• Direct their eyes with breaks and groups
   • Apply the same practices to log files and reports
Electronic Communication

• Be complete, be clear
   •   Which host
   •   Which process / job
   •   What happened (in prose)
   •   How to troubleshoot / resolve the problem


• Start communicating in the subject line

Subject: dbtest1:pg0t log_blaster.ksh FAILURE
Dialog works in any terminal emulator

dialog --menu "Select the database instance“ 0 50 5 
         NICKEL   "Five Cent Database" 
         URANIUM "Not-For-Export Database" 
         CUSTOM   "User defined instance“
Zenity is cooler, but requires X-server
zenity --list 
       --text "Select the database instance" 
       --column "SID" --column "Description" 
                "NICKEL"   "Five Cent Database" 
                "URANIUM" "Not-For-Export Database" 
                "CUSTOM"   "User defined instance“
Communication Wrap-up

Effort without agitation:

   • Work with the user

   • Generous with visual guidance and produce attractive,
     useful log files and reports

   • Clear and complete feedback


Comments or questions
So this is
 Haight
Ashbury
Scalability
• Rule of Extensibility
   • Design for the future
   • Plan to grow


• Scalability goal #1: Never customize a script
   • Overuse variables
   • Never hardcode
       • Passwords
       • Host or database names
       • Paths
   • Use command-line input, „read‟, or parameter files
       • Balance risk vs. maintenance cost
Your Goal: Stability and Predictability

• Consistency
   • Use the same code across your entire enterprise


• Security
   • Limit editing permissions
       • 'Them' and you, too


• Revision control
   • Keep a gold copy out there
   • cfengine
Use the Command Line
 #!/bin/bash                 ${0}     ${1} ${2}
 thisSCRIPT=$0         > backup_db.sh silver hot
 ORACLE_SID=$1
 BU_TYPE=$2
 echo “Executing ${thisSCRIPT} for ${thisSID}”
 if [ ${BU_TYPE} == hot ]; then
    echo “tRunning a hot backup”
    TestForArchiveMode
 else
    RunColdBackup
 fi
Command Line Illustration
    #!/bin/bash
    # file: input_variables.sh

    if [ $1 ] ; then
            echo "Amaze your $1"
    else
            echo “provide input, pathetic human!"
    fi

    >
    > ./input_variables.sh friends
    > Amaze your friends
Command Line Upside
 • Nothing inside the tested script changes
    • No surprises
    • No customizations
    • One script across the enterprise


 • Securable
    • Does not require write permissions for others
Command Line Downside
 • Inflexible
    • If three variables are needed, three must appear


 • Very easy to make a run-time error
    • Not too bad for cron jobs
    • Can be irritating for ad hoc executions


 • Gets out-of-hand with too many variables

    > ./many_input_variables.sh one two three four
      five six seven eight nine ten eleven
Strength and Flexibility
• Use „getopts‟ for command line options
   • Define your own parameters
   • No need for parameter files or script editing


• Accepts defined flags or input values
   • Flexible and scalable
   • Loops through multiple flags


• Parses the command line for hyphens
Syntax

  while getopts ds: thisValue; do
     case $thisValue in
        d) echo "Using default values"
           FILE_NAME=abc123.lst;;
        s) echo "Making the file $OPTARG Gb"
           FILE_SIZE=${OPTARG};;
     esac
  done
Getopts example
 while getopts ds: thisValue; do
    case $thisValue in
       d) echo "Using default values"
         FILE_NAME=abc123.lst;;
       s) echo "Making the file $OPTARG Gb"
          FILE_SIZE=${OPTARG};;
    esac
 Done

  script_name.sh –d –s 20

  Using the default values
  Making the file 20 Gb
Getopts Considerations
 • Very flexible
    • Flags determine which variables are used
    • Not position-sensitive
        • Except if used with non-getopts variables


 • Requires more scripting and testing
    • Same amount of validation
    • Opportunities to use functions


 • Man page is good when you have the concept
    • Steal examples on-line and adapt as needed
Channel the Power

 • Rule of Economy
    • Use machine resources instead of typing


 • Rule of Generation
    • Avoid hand-hacking
    • Write programs to write programs when you can
    • Just like dynamic SQL
Make the Machine do the Work

• Create everything you need, every time
   • Fix permissions too
   • Before and after pictures = Acts of Kindness


             if [ ! -d $thisDIR ]; then
                mkdir $thisDIR
             fi
             echo “Directory before:”
                ls –l
             chmod 775 $thisDIR
             echo “Directory after:”
                ls -l
Resourcefulness

• Single-point maintenance
   • Central script repository
   • Common „data‟ files
       • Host list
       • SID list


• Use existing files
   • /etc/passwd, var/opt/oracle/oratab


• Create your own common files
   • Environment profiles
Scalability Wrap-up

Power without intervention:

   • Editing is never required for a new host / installation


   • Expected problems are handled from the start


   • Existing resources are used


Comments or questions
Quality, craftsmanship, harmony

• Transparency for maintenance and clarity
   • Maintenance without frustration


• Clear communication with the user
   • Effort without agitation


• Scalability without edits
   • Power without intervention
You are a Unix Programmer
“To do the Unix philosophy right, you have to be loyal to excellence.
  You have to believe that software design is a craft worth all the
  intelligence, creativity, and passion you can muster.”
                                     -- Eric S. Raymond
Further Reading


        The Art
           Of
   Unix Programming

     Eric S. Raymond
     Addison-Wesley




      Available at:
    www.powells.com

More Related Content

What's hot

Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Puppet
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationWorkhorse Computing
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Workhorse Computing
 
Overview changes in PHP 5.4
Overview changes in PHP 5.4Overview changes in PHP 5.4
Overview changes in PHP 5.4Tien Xuan
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
Doing It Wrong with Puppet -
Doing It Wrong with Puppet - Doing It Wrong with Puppet -
Doing It Wrong with Puppet - Puppet
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesMarcello Duarte
 
Php pattern matching
Php pattern matchingPhp pattern matching
Php pattern matchingJIGAR MAKHIJA
 

What's hot (20)

New in php 7
New in php 7New in php 7
New in php 7
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Overview changes in PHP 5.4
Overview changes in PHP 5.4Overview changes in PHP 5.4
Overview changes in PHP 5.4
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Subroutines
SubroutinesSubroutines
Subroutines
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
Intro to Perl
Intro to PerlIntro to Perl
Intro to Perl
 
Doing It Wrong with Puppet -
Doing It Wrong with Puppet - Doing It Wrong with Puppet -
Doing It Wrong with Puppet -
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Getting testy with Perl
Getting testy with PerlGetting testy with Perl
Getting testy with Perl
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Php pattern matching
Php pattern matchingPhp pattern matching
Php pattern matching
 

Viewers also liked

UNIX - Class5 - Advance Shell Scripting-P2
UNIX - Class5 - Advance Shell Scripting-P2UNIX - Class5 - Advance Shell Scripting-P2
UNIX - Class5 - Advance Shell Scripting-P2Nihar Ranjan Paital
 
Trouble shoot with linux syslog
Trouble shoot with linux syslogTrouble shoot with linux syslog
Trouble shoot with linux syslogashok191
 
UNIX - Class4 - Advance Shell Scripting-P1
UNIX - Class4 - Advance Shell Scripting-P1UNIX - Class4 - Advance Shell Scripting-P1
UNIX - Class4 - Advance Shell Scripting-P1Nihar Ranjan Paital
 
Karkha unix shell scritping
Karkha unix shell scritpingKarkha unix shell scritping
Karkha unix shell scritpingchockit88
 
Module 13 - Troubleshooting
Module 13 - TroubleshootingModule 13 - Troubleshooting
Module 13 - TroubleshootingT. J. Saotome
 
Advanced Oracle Troubleshooting
Advanced Oracle TroubleshootingAdvanced Oracle Troubleshooting
Advanced Oracle TroubleshootingHector Martinez
 
Linux troubleshooting tips
Linux troubleshooting tipsLinux troubleshooting tips
Linux troubleshooting tipsBert Van Vreckem
 
unix training | unix training videos | unix course unix online training
unix training |  unix training videos |  unix course  unix online training unix training |  unix training videos |  unix course  unix online training
unix training | unix training videos | unix course unix online training Nancy Thomas
 
Process monitoring in UNIX shell scripting
Process monitoring in UNIX shell scriptingProcess monitoring in UNIX shell scripting
Process monitoring in UNIX shell scriptingDan Morrill
 
Fusion Middleware 11g How To Part 2
Fusion Middleware 11g How To Part 2Fusion Middleware 11g How To Part 2
Fusion Middleware 11g How To Part 2Dirk Nachbar
 
25 Apache Performance Tips
25 Apache Performance Tips25 Apache Performance Tips
25 Apache Performance TipsMonitis_Inc
 
Sql server troubleshooting
Sql server troubleshootingSql server troubleshooting
Sql server troubleshootingNathan Winters
 
Linux monitoring and Troubleshooting for DBA's
Linux monitoring and Troubleshooting for DBA'sLinux monitoring and Troubleshooting for DBA's
Linux monitoring and Troubleshooting for DBA'sMydbops
 
Cloug Troubleshooting Oracle 11g Rac 101 Tips And Tricks
Cloug Troubleshooting Oracle 11g Rac 101 Tips And TricksCloug Troubleshooting Oracle 11g Rac 101 Tips And Tricks
Cloug Troubleshooting Oracle 11g Rac 101 Tips And TricksScott Jenner
 
Oracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention TroubleshootingOracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention TroubleshootingTanel Poder
 

Viewers also liked (20)

UNIX - Class5 - Advance Shell Scripting-P2
UNIX - Class5 - Advance Shell Scripting-P2UNIX - Class5 - Advance Shell Scripting-P2
UNIX - Class5 - Advance Shell Scripting-P2
 
Unixshellscript 100406085942-phpapp02
Unixshellscript 100406085942-phpapp02Unixshellscript 100406085942-phpapp02
Unixshellscript 100406085942-phpapp02
 
UNIX - Class1 - Basic Shell
UNIX - Class1 - Basic ShellUNIX - Class1 - Basic Shell
UNIX - Class1 - Basic Shell
 
Trouble shoot with linux syslog
Trouble shoot with linux syslogTrouble shoot with linux syslog
Trouble shoot with linux syslog
 
UNIX - Class4 - Advance Shell Scripting-P1
UNIX - Class4 - Advance Shell Scripting-P1UNIX - Class4 - Advance Shell Scripting-P1
UNIX - Class4 - Advance Shell Scripting-P1
 
Karkha unix shell scritping
Karkha unix shell scritpingKarkha unix shell scritping
Karkha unix shell scritping
 
Module 13 - Troubleshooting
Module 13 - TroubleshootingModule 13 - Troubleshooting
Module 13 - Troubleshooting
 
APACHE
APACHEAPACHE
APACHE
 
Advanced Oracle Troubleshooting
Advanced Oracle TroubleshootingAdvanced Oracle Troubleshooting
Advanced Oracle Troubleshooting
 
Linux troubleshooting tips
Linux troubleshooting tipsLinux troubleshooting tips
Linux troubleshooting tips
 
unix training | unix training videos | unix course unix online training
unix training |  unix training videos |  unix course  unix online training unix training |  unix training videos |  unix course  unix online training
unix training | unix training videos | unix course unix online training
 
Process monitoring in UNIX shell scripting
Process monitoring in UNIX shell scriptingProcess monitoring in UNIX shell scripting
Process monitoring in UNIX shell scripting
 
Fusion Middleware 11g How To Part 2
Fusion Middleware 11g How To Part 2Fusion Middleware 11g How To Part 2
Fusion Middleware 11g How To Part 2
 
25 Apache Performance Tips
25 Apache Performance Tips25 Apache Performance Tips
25 Apache Performance Tips
 
Sql server troubleshooting
Sql server troubleshootingSql server troubleshooting
Sql server troubleshooting
 
Tomcat next
Tomcat nextTomcat next
Tomcat next
 
Tomcat
TomcatTomcat
Tomcat
 
Linux monitoring and Troubleshooting for DBA's
Linux monitoring and Troubleshooting for DBA'sLinux monitoring and Troubleshooting for DBA's
Linux monitoring and Troubleshooting for DBA's
 
Cloug Troubleshooting Oracle 11g Rac 101 Tips And Tricks
Cloug Troubleshooting Oracle 11g Rac 101 Tips And TricksCloug Troubleshooting Oracle 11g Rac 101 Tips And Tricks
Cloug Troubleshooting Oracle 11g Rac 101 Tips And Tricks
 
Oracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention TroubleshootingOracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention Troubleshooting
 

Similar to Linux Shell Scripting Craftsmanship

2010 Smith Scripting101
2010 Smith Scripting1012010 Smith Scripting101
2010 Smith Scripting101bokonen
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World DominationcPanel
 
What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopPuppet
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redisjimbojsb
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best PracticesDavid Keener
 
🐲 Here be Stacktraces — Flink SQL for Non-Java Developers
🐲 Here be Stacktraces — Flink SQL for Non-Java Developers🐲 Here be Stacktraces — Flink SQL for Non-Java Developers
🐲 Here be Stacktraces — Flink SQL for Non-Java DevelopersHostedbyConfluent
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 
Javascript done right - Open Web Camp III
Javascript done right - Open Web Camp IIIJavascript done right - Open Web Camp III
Javascript done right - Open Web Camp IIIDirk Ginader
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidMatthew Johnson
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Damien Seguy
 
Why and How Powershell will rule the Command Line - Barcamp LA 4
Why and How Powershell will rule the Command Line - Barcamp LA 4Why and How Powershell will rule the Command Line - Barcamp LA 4
Why and How Powershell will rule the Command Line - Barcamp LA 4Ilya Haykinson
 
NYPHP March 2009 Presentation
NYPHP March 2009 PresentationNYPHP March 2009 Presentation
NYPHP March 2009 Presentationbrian_dailey
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitStephen Scaffidi
 
gdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptxgdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptxsandeshshahapur
 
React Native Evening
React Native EveningReact Native Evening
React Native EveningTroy Miles
 
Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Prof. Wim Van Criekinge
 

Similar to Linux Shell Scripting Craftsmanship (20)

2010 Smith Scripting101
2010 Smith Scripting1012010 Smith Scripting101
2010 Smith Scripting101
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World Domination
 
What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at Backstop
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redis
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
 
🐲 Here be Stacktraces — Flink SQL for Non-Java Developers
🐲 Here be Stacktraces — Flink SQL for Non-Java Developers🐲 Here be Stacktraces — Flink SQL for Non-Java Developers
🐲 Here be Stacktraces — Flink SQL for Non-Java Developers
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 
Javascript done right - Open Web Camp III
Javascript done right - Open Web Camp IIIJavascript done right - Open Web Camp III
Javascript done right - Open Web Camp III
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue Kid
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 
Why and How Powershell will rule the Command Line - Barcamp LA 4
Why and How Powershell will rule the Command Line - Barcamp LA 4Why and How Powershell will rule the Command Line - Barcamp LA 4
Why and How Powershell will rule the Command Line - Barcamp LA 4
 
NYPHP March 2009 Presentation
NYPHP March 2009 PresentationNYPHP March 2009 Presentation
NYPHP March 2009 Presentation
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's Toolkit
 
gdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptxgdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptx
 
React Native Evening
React Native EveningReact Native Evening
React Native Evening
 
Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013
 
Ansible - A 'crowd' introduction
Ansible - A 'crowd' introductionAnsible - A 'crowd' introduction
Ansible - A 'crowd' introduction
 

Linux Shell Scripting Craftsmanship

  • 1. Shell Scripting Craftsmanship Ray Smith Portland General Electric if [ You can't read this easily ]; then move up closer else Don't say I didn't warn you fi
  • 2. Objectives • Keep you awake until the Opening Keynote • Philosophical alignment • Context of quality • Define craftsmanship • What makes a good quality desk? • What are the common elements of good scripts?
  • 3. • Rule #1: SHELL SCRIPTS MUST WORK • High-visibility tasks • Unforgiving tasks • Repetitive tasks • Rule #2: SCRIPTS MUST KEEP WORKING • Nothing stays the same • Plan on it
  • 4. Quality, craftsmanship, harmony • Transparency • Maintenance without frustration • Clear communication • Effort without agitation • Scalability • Power without intervention
  • 5. Spiritual Guidance • The Art of Unix Programming • Eric S. Raymond • Addison-Wesley • Resident anthropologist and roving ambassador of the open source movement • Three decades of unwritten, hard-won software engineering wisdom from 13 Unix pioneers
  • 6. Transparency • Rule of Robustness • Robustness is the child of transparency and simplicity • Rule of Transparency • Design for visibility, inspection, and debugging • Rule of Simplicity • Design for simplicity • Add complexity only where you must • Rule of Clarity • Clarity is better than cleverness
  • 7. Clear Explanations • Be generous with internal documentation • Particularly when being clever or ultra-efficient # Find all instances of the string find . –type f –exec fgrep –i “$mySTRING” /tmp/dummy {} ; 2>/dev/null • Document dead-ends and surprises • Programming methods that were tried and did not work • „Obvious‟ data sources that are unreliable
  • 8. Predictable Layout • Consistent layout for all your scripts 1. Header block 2. Change log 3. Independent variables 4. Dependent variables 5. Functions 6. Run-time procedure • Take out the guesswork
  • 9. Predictable Layout #!/bin/bash ######################################################### # File : sample_script.sh # Input values : Database name (optional) # Purpose : Amaze others ######################################################## #======================================================= # Independent variables #======================================================= export BASEDIR=/usr/lbin/orascripts #======================================================= # Dependent variables # Nothing to change below this line #======================================================= LOGDIR=$BASEDIR/logs WORKFILE=$LOGDIR/workfile.lst
  • 10. Visual Simplicity • Be kind to yourself and others • Layouts and formatting USE WHITESPACE Break up long lines with back-slash
  • 11. Just like a SQL statement … select distinct table_name,column_name from all_tab_columns where column_name like '%AGREE%' or column_name like '%ANN%„ or table_name like '%ANN%„ or table_name like „%STOR%„ order by table_name,column_name; SELECT DISTINCT table_name,column_name FROM all_tab_columns WHERE column_name LIKE '%AGREE%' OR column_name LIKE '%ANN%„ OR table_name LIKE '%ANN%' OR table_name LIKE '%STOR%' ORDER BY table_name,column_name;
  • 12. Emphasize Visual Flow for thisHOST in `cat ${HOSTLIST}`; do if [ ${#thisHOST} -gt 5 ]; then echo "BIG: ${thisHOST} is ${#thisHOST} characters" else if [ ${#thisHOST} -lt 3 ]; then echo "LITTLE: ${thisHOST} is ${#thisHOST} characters" fi fi done for thisHOST in `cat ${HOSTLIST}`; do if [ ${#thisHOST} -gt 5 ]; then echo "BIG: ${thisHOST} name is long" else if [ ${#thisHOST} -lt 3 ]; then echo "LITTLE: ${thisHOST} name is short" fi fi done
  • 13. Discoverability • Make ${VARIABLES} stand out in your code • Variable naming conventions • ALL_CAPS for session variables • CamelCase for function names • thisVARIABLE for looped variables • Be internally consistent • Adopt a standard and follow it
  • 14. Outstanding Variables for thishost in `cat $hostlist`; do if [ $#thishost -gt 5 ]; then longmessage else if [ $#thishost -lt 3 ]; then shortmessage fi fi done for thisHOST in `cat ${HOSTLIST}`; do if [ ${#thisHOST} -gt 5 ]; then LongMessage else if [ ${#thisHOST} -lt 3 ]; then ShortMessage fi fi done
  • 15. The Penny Wise Quiz a. Shorter variable names = Less typing = Less work b. Obscure variable names = Reduced transparency = Poor quality • Save your cycles for decyphering the logic • Not the variable names
  • 16. Tuning for Transparency • Rule of Optimization • Prototype before polishing • Get it working before you optimize it • Rule of Modularity • Write simple parts connected by clean interfaces • Functions • Temporary files
  • 17. Efficiency • Use shell script functions function SetPerms770 { echo “nSetting permission to 770 for ${thisFILE}” chmod 770 ${thisFILE}/* } > for thisFILE in `cat ${FILELIST}`; do > SetPerms770 > done • Modularize all repeated code statements
  • 18. Handiest function ever • At the beginning of the script • At the end of the script • Any time execution might end function CleanUpFiles { [ $LOGFILE ] && rm –f ${LOGFILE} [ $SPOOL01 ] && rm –f ${SPOOL01} }
  • 19. # Functions # ------------------------------------------------------------------- function CopyFiles { cd $SOURCE_DIR ls -1 | grep -i $ORACLE_SID >$WORKFILE for thisFILE in `cat $WORKFILE`; do SOURCE_FILE=$SOURCE_DIR/$thisFILE TARGET_FILE=$TARGET_DIR/$thisFILE cp –f $SOURCE_FILE $TARGET_FILE done rm -f ${WORKFILE} } # ------------------------------------------------------------------- # Run-time procedure # • Modularize all repeated code statements ------------------------------------------------------------------- SOURCE_DIR=${GOLD_DIR}/rman TARGET_DIR=${LIVE_DIR}/rman CopyFiles SOURCE_DIR=${GOLD_DIR}/security TARGET_DIR=${LIVE_DIR}/security CopyFiles
  • 20. Transparency Zen • Rule of Diversity • Distrust all claims of “one true way” • Including your own • Revisit older scripts • Technologies change • Techniques change
  • 21. The Secret to the (Scripting) Universe Steal Adapt Improve Repeat
  • 22. Transparency Wrap-up Maintenance without frustration: • Written with maintenance and on-call in mind • Provide useful guidance and instructions • Reflect visual simplicity and clear layout Comments or questions
  • 24. User Communication • Rule of Silence • Nothing surprising to say: say nothing • Rule of Repair • Repair what you can • When you must fail, fail noisily and as soon as possible • Rule of Least Surprise • In interface design, do the least surprising thing • Do the most expected thing
  • 25. Work with the user • Verify scripted actions echo “These files will be backed up:” cat ${FILELIST} • Keep the user informed • Share status and decisions echo “You asked to delete everything in /etc” read -p "Is this correct? [Y|N]" myVal case $myVal in . . .
  • 26. Opatch is a gem Running prerequisite checks... OPatch detected non-cluster Oracle Home from the inventory and will patch the local system only. Please shutdown Oracle instances running out of this ORACLE_HOME on the local system. (Oracle Home = '/cisp_orabase/product/10.2.0') Is the local system ready for patching? [y|n] User Responded with: Y Applying patch 7155252... ApplySession applying interim patch '7155252' to OH '/cisp_orabase/product/10.2.0' Backing up files affected by the patch '7155252' for rollback. This might take a while...
  • 27. Graciousness • Handle errors with grace • Explain the situation • Lead the user to a solution if [ ${#1} -eq 0 ];then echo "The required value for database name" echo "was not passed in the command line" read -p "Enter the database name: " myVal export thisSID=$myVal fi
  • 28. Communicating Failure • Cryptic feedback is not welcome nor helpful > > FATAL ERROR: bckpinit_strt error 12 > • Terminal output is free, use it if you need it > > File not found: bckpinit_strt.conf > > Corrective action required: > Verify bckpinit_strt.conf exists at ABC > and readable by user xyz > Email notification has been sent
  • 29. Signs of Life • Same script should work in cron or interactive • Test for tty (terminal id) if tty –s then echo “Oh good, this is interactive” echo “Hello $USER” else date +“Script $0 started %T” >> $LOGFILE fi
  • 30. Artist and Psychologist • Break the output into usable blocks • Use n and t liberally • If it makes it easier for user to understand • Particularly important for interactive scripts • Push the „read‟ statement into their attention • “Is the local system ready for patching? [y|n]” • Direct their eyes with breaks and groups • Apply the same practices to log files and reports
  • 31. Electronic Communication • Be complete, be clear • Which host • Which process / job • What happened (in prose) • How to troubleshoot / resolve the problem • Start communicating in the subject line Subject: dbtest1:pg0t log_blaster.ksh FAILURE
  • 32.
  • 33. Dialog works in any terminal emulator dialog --menu "Select the database instance“ 0 50 5 NICKEL "Five Cent Database" URANIUM "Not-For-Export Database" CUSTOM "User defined instance“
  • 34. Zenity is cooler, but requires X-server zenity --list --text "Select the database instance" --column "SID" --column "Description" "NICKEL" "Five Cent Database" "URANIUM" "Not-For-Export Database" "CUSTOM" "User defined instance“
  • 35. Communication Wrap-up Effort without agitation: • Work with the user • Generous with visual guidance and produce attractive, useful log files and reports • Clear and complete feedback Comments or questions
  • 36. So this is Haight Ashbury
  • 37. Scalability • Rule of Extensibility • Design for the future • Plan to grow • Scalability goal #1: Never customize a script • Overuse variables • Never hardcode • Passwords • Host or database names • Paths • Use command-line input, „read‟, or parameter files • Balance risk vs. maintenance cost
  • 38. Your Goal: Stability and Predictability • Consistency • Use the same code across your entire enterprise • Security • Limit editing permissions • 'Them' and you, too • Revision control • Keep a gold copy out there • cfengine
  • 39. Use the Command Line #!/bin/bash ${0} ${1} ${2} thisSCRIPT=$0 > backup_db.sh silver hot ORACLE_SID=$1 BU_TYPE=$2 echo “Executing ${thisSCRIPT} for ${thisSID}” if [ ${BU_TYPE} == hot ]; then echo “tRunning a hot backup” TestForArchiveMode else RunColdBackup fi
  • 40. Command Line Illustration #!/bin/bash # file: input_variables.sh if [ $1 ] ; then echo "Amaze your $1" else echo “provide input, pathetic human!" fi > > ./input_variables.sh friends > Amaze your friends
  • 41. Command Line Upside • Nothing inside the tested script changes • No surprises • No customizations • One script across the enterprise • Securable • Does not require write permissions for others
  • 42. Command Line Downside • Inflexible • If three variables are needed, three must appear • Very easy to make a run-time error • Not too bad for cron jobs • Can be irritating for ad hoc executions • Gets out-of-hand with too many variables > ./many_input_variables.sh one two three four five six seven eight nine ten eleven
  • 43. Strength and Flexibility • Use „getopts‟ for command line options • Define your own parameters • No need for parameter files or script editing • Accepts defined flags or input values • Flexible and scalable • Loops through multiple flags • Parses the command line for hyphens
  • 44. Syntax while getopts ds: thisValue; do case $thisValue in d) echo "Using default values" FILE_NAME=abc123.lst;; s) echo "Making the file $OPTARG Gb" FILE_SIZE=${OPTARG};; esac done
  • 45. Getopts example while getopts ds: thisValue; do case $thisValue in d) echo "Using default values" FILE_NAME=abc123.lst;; s) echo "Making the file $OPTARG Gb" FILE_SIZE=${OPTARG};; esac Done  script_name.sh –d –s 20  Using the default values  Making the file 20 Gb
  • 46. Getopts Considerations • Very flexible • Flags determine which variables are used • Not position-sensitive • Except if used with non-getopts variables • Requires more scripting and testing • Same amount of validation • Opportunities to use functions • Man page is good when you have the concept • Steal examples on-line and adapt as needed
  • 47. Channel the Power • Rule of Economy • Use machine resources instead of typing • Rule of Generation • Avoid hand-hacking • Write programs to write programs when you can • Just like dynamic SQL
  • 48. Make the Machine do the Work • Create everything you need, every time • Fix permissions too • Before and after pictures = Acts of Kindness if [ ! -d $thisDIR ]; then mkdir $thisDIR fi echo “Directory before:” ls –l chmod 775 $thisDIR echo “Directory after:” ls -l
  • 49. Resourcefulness • Single-point maintenance • Central script repository • Common „data‟ files • Host list • SID list • Use existing files • /etc/passwd, var/opt/oracle/oratab • Create your own common files • Environment profiles
  • 50. Scalability Wrap-up Power without intervention: • Editing is never required for a new host / installation • Expected problems are handled from the start • Existing resources are used Comments or questions
  • 51. Quality, craftsmanship, harmony • Transparency for maintenance and clarity • Maintenance without frustration • Clear communication with the user • Effort without agitation • Scalability without edits • Power without intervention
  • 52. You are a Unix Programmer “To do the Unix philosophy right, you have to be loyal to excellence. You have to believe that software design is a craft worth all the intelligence, creativity, and passion you can muster.” -- Eric S. Raymond
  • 53. Further Reading The Art Of Unix Programming Eric S. Raymond Addison-Wesley Available at: www.powells.com