shell_example01

  • input and output,user input
  • if
  • exit statues
  • functions
  • wildcards
  • for loops
  • case statements
  • logging
  • debugging tips
  • bash shell options
  • more

  • download
    shell-script-course/debugging/lessons
    shell-script-course/debugging/practice-exercies

  • learn
    1 use variable
    2 perform tests and make decisions
    3 accept command line arguments
    4 accept input from a user

demo

    #!/bin/bash 
    echo "scripting is fun!" 
    --------------------------    
    chmod 755 script.sh 
    ./script.sh

not just shell script

    #!/usr/bin/python 
    print "this is a python script" 
    ------------------------------
    chmod 755 hi.py 
    ./hi.py

Variables

  • storage locations that have a name
  • name-value pairs
  • uppercase,case sensitive
  • VARIABLE_NAME="Value"

Variable Usage

    #!/bin/bash 
    MY_SHELL="bash" 
    echo "I like the $MY_SHELL shell."
    #!/bin/bash 
    MY_SHELL="bash"
    echo "I like the ${MY_SHELL} shell."
    #!/bin/bash
    MY_SHELL="bash"
    echo "I am ${MY_SHELL}ing on my keyboard."
    
    OUTPUT:
    I am bashing on my keyboard.
    #!/bin/bash
    MY_SHELL="bash"
    echo "I am $MY_SHELLing on my keyboard."
    
    OUTPUT:
    I am  on my keyboard.
    #!/bin/bash
    SERVER_NAME=$(hostname)
    echo "you are running this script on ${SERVER_NAME}."
    
    OUTPUT:
    you are running this script on linuxsvr.
    #!/bin/bash
    SERVER_NAME=`hostname`
    echo "you are running this script on ${SERVER_NAME}."
    
    OUTPUT:
    you are running this script on linuxsvr.

Variable Names(等号前后不能有空格)

  • valid:

    • FIRST3LETTERS="ABC"
    • FIRST_THREE_LETTERS="ABC"
    • firstThreeLetters="ABC"
  • Invalid:

    • 3LETTERS="ABC"
    • first-three-letters="ABC"
    • first@Three@Letters="ABC"

Tests:success:0 failed:1

  • Syntax:
    • [ condition-to-test-for ]
  • Example:
    • [ -e /etc/passwd ]

File operators(tests)

    -d FILE     ture if file is directory.
    -e FILE     true if file exists.   
    -f FILE     true if file exists and is a regular file
    -r FILE     true if file is readable by you
    -s FILE     true if file exists and is not empty.
    -w FILE     true if file is writable to you.
    -x FILE     true is file is executable by you.

String operators(tests)

    -z STRING   true if string is empty.
    -n STRING   true if string is not empty.
    STRING1=STRING2     true is the strings are equal.
    STRING1!=STRING2    true is the strings are not equal.

Arithmetic operators(tests)

    arg1 -eq arg2
    arg1 -ne arg2
    
    arg1 -lt arg2
    arg1 -le arg2
    
    arg1 -gt arg2
    arg1 -ge arg2

Making Decisions - The if statement

    if [ condiction-is-true ]
    then
        command 1
        command 2
        command N
    fi
    #!/bin/bash
    MY_SHELL="bash"
    if [ "$MY_SHELL" = "bash" ]
    then
        echo "you seen to like the bash shell."
    fi
    
    OUTPUT:
    you seen to like the bash shell.

if/else

    if [ condition-is-true ]
    then
        command N
    else
        command N
    fi
    #!/bin/bash
    MY_SHELL="csh"
    if [ "$MY_SHELL" = "bash" ]
    then
        echo "you seem to like bash shell."
    else
        echo "you don't seem to like bash shell."
    fi

if/elif/else

    if [ condiction-is-true ]
    then
        command N
    elif [ condition-is-true ]
    then
        command N
    else 
        command N
    fi  
    #!/bin/bash
    MY_SHELL="csh"
    if [ "$MY_SHELL" = "bash" ]
    then
        echo "you seem to like bash shell."
    elif [ "$MY_SHELL" = "csh" ]
    then
        echo "you don't seem to like csh shell."
    else
        echo "you don't seem to like csh or bash shells."
    fi

For loop

    for VARIABLE_NAME in ITEM1 ITEM_N
    do
        command 1
        command 2
        command N
    done    
    #!/bin/bash
    for COLOR in red green blue
    do
        echo "COLOR: $COLOR"
    done
   OUTPUT:
   COLOR: red
   COLOR: green
   COLOR: blue
    #!/bin/bash
    COLORS="red green blue"
    
    for COLOR in $COLORS
    do
        echo "COLOR: $COLOR"
    done
   OUTPUT:
   COLOR: red
   COLOR: green
   COLOR: blue
    #!/bin/bash
    PICTURES=$(ls *jpg)
    DATE=$(date +%F)
    for PICTURE in $PICTURES
    do
        echo "Renaming ${PICTURE} to ${DATE}-${PICTURE}"
        mv ${PICTURE} ${DATE}-${PICTURE}
    done
    
    OUTPUT:
    $ ls
    bear.jpg
    $ ./rename-pics.sh
    Renaming bear.jpg to 2015-03-06-bear.jpg
    $ ls
    2015-03-06-bear.jpg 

parameters 0 -9

  • todo

Exit statuses

  • how to check the exit status of a command
  • how to make decisions based on the status
  • how to use exit statuses in your own scripts

Exit Status / Return Code

  • Every command returns an exit status
  • Range from 0 to 255
  • 0 = success
  • Other than 0 = error condition
  • Use for error checking
  • Use man or info to find meaning of exit status

Checking the exit status

  • $? contains the return code of the previously executed command.
    ls /not/here
    echo "$?"
    
    OUTPUT:
    2
    HOST="google.com"
    ping -c l $HOST
    if [ "$?" -eq "0" ]
    then
        echo "$HOST reachable."
    else
        echo "$HOST unreachable."
    fi     
    HOST="google.com"
    ping -c l $HOST
    if [ "$?" -nq "0" ]
    then
        echo "$HOST unreachable."
    fi     
    HOST="google.com"
    ping -c l $HOST
    RETURN_CODE=$?
    
    if [ "$RETURN_CODE" -ne "0" ]
    then
        echo "$HOST unreachable."
    fi     

&& and ||

  • && = AND (前一个是true,后一个才会执行)
    mkdir /tmp/bak && cp test.txt /tmp/bak/
  • || = OR (前一个是false,后一个才会执行)
    cp test.txt /tmp/bak/ || cp test.txt /tmp
    #!/bin/bash
    HOST="google.com"
    ping -c l $HOST && echo "$HOST reachable."
    #!/bin/bash
    HOST="google.com"
    ping -c l $HOST || echo "$HOST unreachable."

The semicolon ;

  • separate commands with a semicolon to ensure they all get executed.
  • 和前一个命令是否成功无关,命令都会被执行,和换行是一个意思
    cp test.txt /tmp/bk/ ; cp test.txt /tmp
    #Same as:
    cp test.txt /tmp/bk/
    cp test.txt /tmp

Exit command

  • Explicitly define the return code
    • exit 0 -- 255
  • the default value is that of the last command executed
  • 脚本的任何地方都可以使用exit命令
    HOST="google.com"
    ping -v 1 $HOST
    if [ "$?" -ne "0" ]
    then
        echo "$HOST unreachable."
        exit 1
    fi
    exit 0

Summary

  • all command return an exit status
  • 0 - 255
  • 0 = success
  • other than 0 = error condition
  • $? contains the exit status
  • Decision making -if , &&, ||
  • exit

Functions

  • why to use functions
  • how to create them
  • how to use them
  • variable scope
  • function parameters
  • exit statuses and return codes

Functions

  • if you're repeating yourself ,use a function.
  • reusable code
  • must be defined before use
  • has parameter support
    function function-name(){
        #code goes here
      }
    
    function-name(){
        #code goes here
    }
    
    #!/bin/bash
    function hello(){
        echo "Hello!"
    }
    hello
    #!/bin/bash
    function hello(){
        echo "hello!"
        now
    }
    function now(){
        echo "It's $(date +%r)"
    }
    hello
    #!/bin/bash
    function hello(){
        echo "hello!"
        now
    }
    hello # 会报错的
    function now(){
        echo "It's $(date +%r)"
    }

Positional Parameters

  • functions can accept parameters
  • the first parameter is stored in $1
  • the second parameter is stored in $2, etc.
  • $@ contains all of the parameters
  • just like shell scripts.
    • $0 = the script itself, not function name
    #!/bin/bash
    function hello(){
        echo "Hello $1"
    }
    hello Jason
    
    # OUTPUT:
    # Hello Jason
    #!/bin/bash
    function hello(){
        for NAME in $@
        do  
            echo "hello $NAME"
        done
    }
    
    hello jason dan ryan
    # OUTPUT:
    # Hello jason
    # Hello dan
    # Hello v    

variable scope

  • by default, variables are global
  • variable have to be defined before used.
    GLOBAL_VAR=1
    # GLOBAL_VAL is available
    # in the function.
    my_function
    # GLOBAL_VAL is NOT available
    # in the function.
    my_function
    GLOBAL_VAR=1
    #!/bin/bash
    my_function(){
       GLOBAL_VAR=1 
    }
    
    # GLOBAL_VAL is NOT available yet
    echo $GLOBAL_VAR
    my_function
    # GLOBAL_VAL is NOW available yet
    echo $GLOBAL_VAR

local Variables

  • can only be accessed within the function.
  • create using the local keyword
    • local LOCAL_VAR=1
  • only functions can have local variables
  • best practice to keep variables local in functions

Exit Status(Return Code)

  • functions have an exit status

  • explicitly

    • return <RETURN_CODE>
  • Implicity

    • the exit status of the last command executed in the function
  • Valid exit codes range from 0- 255

  • 0 = success

  • $?=the exit status

    my_function
    echo $?
    # todo :.

Summary

  • DRY(don't repeat yourself)
  • global and local variables
  • parameters
  • exit statuses

Wildcards

  • *-matches zero or more characters

    • *.txt
    • a*
    • a*.txt
  • ?-matches exactly one character

    • ?.txt
    • a?
    • a?.txt

More Wildcards-Character Classes

  • []- a character class

    • matches any of the characters include between the brackets.
      matches exactly one character.
    • [aeiou]
    • ca[nt]*
      • can
      • cat
      • candy
      • catch
  • [!]- matches any of the characters NOT included between the brackets.
    matches exactly one character

    • [!aeiou]*
      • baseball
      • cricket

more wildcards - Ranges

  • User two characters separated by hyphen to create range in a
    character class.

  • [a-g]*

    • matches all files that start with a,b,c,...g
  • [3-6]*

    • matches all files that start with 3,4,5,6

Name character class

  • [[:alpha:]] 字母
  • [[:alnum:]] 数字字母
  • [[:digit:]] 数字
  • [[:lower:]] 小写字母
  • [[:space:]] 字符
  • [[:upper:]] 大写字母

Mathching wildcard patterns

  • -escape character. use if you want to match a wildcard
    character
    • match all files that end with a question mark:
      • *?
        • done?

summary

  • ?
  • []
  • [0-3]
  • [[:digit:]]

why use wildcards?

  • wildcards are great when you want to work on a group of files or directories.
    #!/bin/bash
    cd /var/www
    cp *.html /var/www-just-html
    #!/bin/bash
    cd /var/www
    for FILE in *.html
    do
        echo "copy $FILE"
        cp $FILE /var/www-just-html
    done
    
    OUTPUT:
    copy about.html
    copy content.html
    copy index.html
    #!/bin/bash
    
    for FILE in /var/www/*.html
    do
        echo "copy $FILE"
        cp $FILE /var/www-just-html
    done
    
    OUTPUT:
    copy /var/www/about.html
    copy /var/www/content.html
    copy /var/www/index.html

summary

  • just like on the command line.
  • in loops
  • supply a directory in the wildcard or use the cd command to change the current directory

Case Statements

  • alternative to if statements
    • if ["$VAR"="one"]
    • elif ["$VAR"="two"]
    • elif ["$VAR"="three"]
    • elif ["$VAR"="four"]
  • may be easier to read than complex if statements
case "$VAR" in
    pattern_1)
        # commands go here
        ;;
    patter_N)
        # commands go here    
        ;;
esac
    case "$1" in
        start)
            /usr/sbin/sshd
            ;;
        stop)
            kill $(cat /var/run/sshd.pid)
            ;;
    esac           
    case "$1" in
        start)
            /usr/sbin/sshd
            ;;
        stop)
            kill $(cat /var/run/sshd.pid)
            ;;
        *)
            echo "Usage: $0 start|stop" ; exit 1
            ;;    
    esac           
    case "$1" in
        start|START)
            /usr/sbin/sshd
            ;;
        stop|STOP)
            kill $(cat /var/run/sshd.pid)
            ;;
        *)
            echo "Usage: $0 start|stop" ; exit 1
            ;;    
    esac           
    read -p "Enter y or n: " ANSWER
    case "$ANSWER" in
        [yY]|[yY][eE][sS])
            echo "your answered yes."
            ;;
        [nN]|[nN][oO])
            echo "your answered no."
            ;;
        *)
            echo "Invalid answer."
        ;;
     esac                   
    read -p "Enter y or n: " ANSWER
    case "$ANSWER" in
        [yY]*)
            echo "your answered yes."
            ;;
        *)
            echo "Invalid answer."
        ;;
     esac                   

summary

  • can be used in place of if statements.
  • patterns can include wildcards.
  • multiple pattern matching using a pipe.

Logging

what you will learn

  • why log
  • Syslog standard
  • Generating log messages
  • Custom logging functions

Logging

  • Logs are the who ,what , when, where ,and why
  • Output may scroll of the screen
  • Script may run unattended(via cron, etc)

todo:

summary

  • Why log
  • syslog standard
  • Generating log messages
  • Custom logging functions

while loops

  • what you will learn
  • while loops
  • infinite loops
  • loop control
    • explicit number of times
    • user input
    • command exit status
  • reading files, line-by-line
  • break and continue
    while [ condition_is _true ]
    do
        command 1
        command 2
        command N
    done
    while [ condition_is_true ]
    do
        # commands change the condition
        command 1
        command 2
        command N
    done

infinite loops

    while [ condition_is_true ]
    do
        # commands do not change
        # the condition
        command N  
    done
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,319评论 0 10
  • 其实上周就想写,内心认定对人尤其是女人来讲有多重要。这主要是我看到了冯唐的一篇老文引发的思考,坦白讲,冯唐的文风赤...
    小仙儿77阅读 844评论 0 1
  • 第一章 顾念卿坐在海棠花下,一口一口喝着酒,有一搭没一搭的把弄着花瓣。她想,就...
    是尤小绿呀阅读 282评论 0 1
  • 01厨房物品该舍弃的舍弃,不要贪图便宜,收拾厨房,把家里之前不知什么时间存放的一次性物品都给扔掉了。 02买东西也...
    小惠_f2b8阅读 123评论 0 1
  • 车大王(CHEDAWANG)又名:车代网,隶属于胜旗网络科技有限公司。 车大王自成立以来,就致力于成为全国性的汽车...
    襄陽余誌遠阅读 190评论 0 0