bash

  1. bash

  2. Writing and Debugging scripts. 

    1. creating and running a scrip   

      1. writing and naming

        • script = sequence of commands
        • 同名のスクリプトに注意
          • which -a (all matchig pathnames) script_name
          • whereis script_name
          • locate script_name
      2. script1.sh

        1. export PATH="$PATH":~/scripts(~/scrpt中にscriptをいれる)
        2. #!/bin/bash
          clear
          echo "The script starts now"
          echo "Hi, $USER!"
          echo
          echo "Iwill now fetch you a list of connected users:"
          echo
          w
          echo
          echo "I'm setting two variables now."
          COLOUR="black"
          VALUE="9"
          echo "This is a string : $COLOUR"
          echo "And tis is a number : $VALUE"
          echo
          echo "I'm giving you back your prompt now."
          echo

      3. script execute permission
        • chmod u+x script1.sh
        • pathを設定していないときは ./script_name.shで実行
        • rbash (or sh, bash) script_name.sh で他のシェルでの挙動を見る事ができる(source script_name.shで現在のシェルで実行)
    2. script basics

    3. debugging bash scripts

      1. スクリプト全体のデバグはサブシェルを-x optionでスタートさせる(bash -x script1.sh)事でできる。
      2. 部分的にデバグするにはscript中に
        • set -x
          w
          set +x
          のように使ってwの挙動を見る
      3. set (debugging) options のoverview
        short notation
        long notation
        result
        set -f
        set -o
        noglob
        *を使用時のファイル名生成をできなくする
        set -v
        set -o
        verbose
        shell  input lines をprint
        set -x
        set -o
        xtrace
        実行前にcommands trace をprint
        • -はオプションを活性化、+は不活性化
        • set -v : ls -> ls ...
        • set -f :
          •  ls * -> nosuch file or directory
          • touch * -> * というファイル生成
          • rm * -> *消失
  3. The bash environment

    1. shell initialization files

      1. system-wide configuration files
        1. /etc/profile
        2. /etc/bashrc
      2. individual user configuration files
        1. ~/.bash_profile (add extraconfiguration)
        2. ~/.bash_login
        3. ~/..profile
        4. ~/.bashrc (非ログインシェルの起動時に実行される)
        5. ~/.bash_logout
      3. changing shell configuration files
    2. variables

        1. shell variables はupper case で表示. bashは2タイプの変数
          1. global variables(or environmntal variables): env or printenv で表示
          2. Local variables
          3. variables by content
            • string variables
            • Integer variables
            • Constant variables
            • Array variables
        2. creating variables
          • case-sensitiveかつ数字で始まることは許されない。
          • varname="value"でセットする。=周辺のスペースはエラーとなる。""で囲むのがエラーを避けるためのよい習慣。
        3. exporting variables
          • 上記のlocal variable はchild processからは認識されない。subshellに渡すにはexport command を使う。
          • export varname="value"
          • full_name="Franky  M.Singh"
            bash
            echo $full_name  -->なし
            exit
            export full_name
            bash
            echo $full_name --> Franky M.Singh
            export full_name="Charles the Great"
            echo $full_name  --> Charles the Great
            exit
            echo $full_name --> Frankey M.Singh

            parentでFranky--をexportして
            subshell(Frankyをexpoted)の変数値を変える
            parentの変数値は不変

        4. Reserved variables
        5. special parameters
          • $*   :positional parameterにexpand
          • $@ :仝
          • $#   :number of positional parameterに
          • $?   :直近の実行されたパイプラインのexit status
          • $-   :option flags
          • $$  :process ID
          • $!   :backgroundで直近に実行されたprocessID
          • $0  :shell名
          • $_  :last argument等(argument listに渡された絶対ファイル名等)
          • #!/bin/bash
            # positional.sh
            # This script reads 3 positional parameters and prints them out
            POSPAR1="$1"
            POSPAR2="$2"
            POSPAR3="$3"
            echo "$1 is the first positional parameter ,\$1."
            echo "$2 is the second positional parameter ,\$2."
            echo "$3 is the third positional parameter ,\$3."
            echo
            echo "The total number of positional parameters is $#."

            positional.sh one two three four five

          • grep dictionary /usr/share/dict/words
            dictionary
            echo $_
            /usr/share /dict/words
          • echo $$ -->10662
          • mozilla &
            [1] 11064
            echo $!
            11064 (bg)
          • echo $0 --> bash
          • echo $? --> 0 (exit code =0)
            ls doesnotexist -=> ls:doesnotexist:No such file
            echo $? --> 1 (error code)
        6. script recycling with variables(下の方がより洗練されたスクリプト)
          • #!/bin/bash

            # This script makes a backup of my home directory.

            cd /home

            # This creates the archive
            tar cf /var/tmp/home_ouryouji.tar ouryouji > /dev/null 2>&1

            # First remove the old bzip2 file. Redirect errors because this generates some if the archive
            # does not exist. Then create a new compressed file.
            rm /var/tmp/home_ouryouji.tar.bz2 2> /dev/null
            bzip2 /var/tmp/home_ouryouji.tar

            # Copy the file to another host - we have ssh keys for making this work without intervention.
            scp /var/tmp/home_ouryouji.tar.bz2 bordeaux:/opt/backup/ouryouji > /dev/null 2>&1

            # Create a timestamp in a logfile.
            date >> /home/ouryouji/log/home_backup.log
            echo backup succeeded >> /home/ouryouji/log/home_backup.log
          • #!/bin/bash

            # This script makes a backup of my home directory.

            # Change the values of the variables to make the script work for you:
            BACKUPDIR=/home
            BACKUPFILES=ouryouji
            TARFILE=/var/tmp/home_ouryouji.tar
            BZIPFILE=/var/tmp/home_ouryouji.tar.bz2
            SERVER=bordeaux
            REMOTEDIR=/opt/backup/ouryouji
            LOGFILE=/home/ouryouji/log/home_backup.log

            cd $BACKUPDIR

            # This creates the archive
            tar cf $TARFILE $BACKUPFILES > /dev/null 2>&1

            # First remove the old bzip2 file. Redirect errors because this generates some if the archive
            # does not exist. Then create a new compressed file.
            rm $BZIPFILE 2> /dev/null
            bzip2 $TARFILE

            # Copy the file to another host - we have ssh keys for making this work without intervention.
            scp $BZIPFILE $SERVER:$REMOTEDIR > /dev/null 2>&1

            # Create a timestamp in a logfile.
            date >> $LOGFILE
            echo backup succeeded >> $LOGFILE
          • command >/dev/null 2>&1: コマンドの出力を/dev/null, errorを1(/dev/null?)ということであるがcat echo等は出力があるがtarにはない。
          • 大きなdirectoryのbackupにはrsyncを使う
    3. Quoting characters

      1. characters の特別な意味を消すためにクオートされる。
      2. escape character \
        • date=20021226
          echo $date --> 20021226
          echo \$date --> $date
      3. single quotes
        • ''で囲まれた文字のliteral valueを保存する。\で先行されてもsingle quote中のsingle quoteは置けない。
        • echo '$date' --> $date
      4. double quotes
        • $,``,\を除いた文字のリテラル値を保存.
        • \は次に$,`,",\ 或いはnewlineが続くときだけその意味を保持する。""中で\ははこれらの文字が続くとき入力から除かれる.特異な意味を持たない文字は不変。
        • ""中で"は\でクオートできる
        • echo "$date" --> 20021226
          echo "`date`" --> SunApr20 11:12:22
          echo "I'd say \"Go for it!\"" --> I'd say "Go for it!"
          echo "\"    More input>
          echo "\\" --> \
    4. Shell expansion

      1. general
      2. Brace expansion
        • pattern: preamble + {comma-separated strings} + postscript
        • echo sp{el,il,al}l -> spell spill spall (textualのみ)
        • ${ はconflictを避けるため不適格
      3. Tilda expansion(重要でないと思われる。省略)
      4. shell parameter and variable expansion
        • "$ "は,parameter expansion, command expansion, arithmetic expansion を導入する。{}はオプションだが、${parameter}の形で、パラメータが置換され、$直後のcharacter expandから保護される。
        • straight parameter expansion例:echo $SHELL
        • echo ${!S*}では!の残りのパラメータ部から作られる変数の値を変数の名前とする。(indirect expansion)
          • echo ${!S*}-> SECONDS SHELL SHELLOPTS SHLVL となる
        • named value を作る:${VAR:=value}
        • example
          echo $FRANKY --> no output
          echo ${FRANKY:=Franky} --> Franky
           (しかしspecial parameter 特にpositional parameterはこの方法では割り当てできない。)
      5. command substitution
        • $(command) 或いは `command`でコマンドの出力をコマンド自体で置換。
      6. arythmetic expansion
        • $((EXPRESSION))のformat.
        • (( ))中のexpressionは""中のように扱われる。
      7. process substitution
        • <(LIST) -- ファイルが読まれて出力
        • >(LIST) -- ファイルに書く
        • > <と( )の間にスペースがあってはならない。さもなくてはredirectionと訳される。
          • 例: cat <file1, echo to be written >file2
      8. word splitting
        • ""中で起こったものでないparameter expansion,command substitution, arythmetic expansionについてword splitting scanする。(IFS)
          • # 第1引数を echo する関数
            function echo_first {
            echo $1
            }

            # スペース区切りの文字列を含む変数
            var="a b c"



            ### Bash の場合

            echo_first $var # => a
            echo_first "$var" # => a b c

            for v in $var; do
            echo $v
            done
            # => a
            # => b
            # => c

            vor v in "$var"; do
            echo $v
            done
            # => a b c

      9. filename expansion
        • word splitting 後,-f optionがセットされていないなら、bashは各語に * , ?, [ を探してpattern matching を行い,ソートされたファイル名と置き換える。
    5. Aliases

      1. What are aliases?
        • コマンド: alias unalias
      2. Creating and removing aliases
        • alias dh = 'df -h' dh
        • unalias dh dh
    6. More Bash options

      1. Displaying options
        • set -o で表示
      2. changing options
        • 以下はPOSIX--compatible mode で実行可 bash --posix script.sh
        • 一時的に現在の環境を変えるにはset -(enable), set +(disable)を使う。
        • set -o noclobber (redirection命令でファイル上書きさせない).
          touch test
          date > test :cannot overwrite existing file
          set +o noclobber
          date >  test
        • -u(unset variablesをエラーとみなす)
          echo $VAR --- 表示なし
          set -u
          echo $VAR --> unbound variable
          set +u
        • set -o noglob (special character をexpand されないようにする)
          touch *
          ls -l   *    --rw-rw---|     -- *
  4. Regular expressions

    1. 0
      1. What are regular expressions?
      2. regular expression metacharacters
      3. basic versus extended regular expressions
    2. examples using grep
      1. grepはinput file の行を探しstandard output に行をコピーする(by default)
        • grep root /etc/passwd  -> "root"
        • grep -n root /etc/passwd  行番号表示
        • grep -v bash /etc/passwd | grep -v nologin (bash不使用かつnologin shell使用でないもの---どのユーザがbashを使っているかチェックするがnologin shellのaccountsは表示されない)
        • grep -c false /etc/passwd (そしてshellとして/bin/falseをもつaccountの数を数える)
        • grep -i ps ~/.bash* | grep -v history (~/.bashから始まる全ディレクトリの全ファイルからhistoryという文字を除く大小文字の"ps"を行表示)
      2. grep and regular expressions
        1. Line and word anchors
          • "root"で始まるline: grep ^root /etc/passwd
          • ":"で終わる行: grep :$ /etc/passwd
          • PATHがエクスポートされた事をチェック:grep export ~/.bashrc | grep '\<PATH' (MANPATH等の表示を避ける)
          • \>はend of wordにマッチ
          • separate wordを探すには-wを使う。
        2. character classes []
          • [^...] NOT in the list
          • [0123456789] any single digit
          • [a-d] abcd
          • grep [yf] /etc/passwd yかfを含む行すべて
          • ls *[1-9].xml  &cir;&cir;1.xmlなど
        3. wild cards
          1. cで始まりhで終わる5文字のchar: grep '\<c...h\>'  /usr/share/dict/words
          2. -F option: grep -F '*' /etc/profile
          3. grep '\<c*h\>  /usr/share/dict/words
      3. pattern matching using bash features
        1. character ranges (grepから離れてshellで直接使う方法)
        2. charcter classes
          1. ls -ld [[:digit:]]*
          2. ls -ld [[:upper:]]*
  5. The GNU sed stream editor

    1. Introdution

      1. What is sed
      2. sed commands
        command
        result
        a\
        c\
        d
        i\
        p
        r
        s
        w
        append text below current line
        change text in the current line with new text
        delete text
        insert text above current line
        print text
        read s file
        search and replace
        write to afile

        option
        effect
        -e
        script
        script中にコマンドセットを入れて走らせる
        -f
        SCRIPT-FILEファイル中に含まれるコマンドを付加し走らせる。
        -n
        silent mode
        -V
        print version information and exit

    2. Interactive editing

      1. printing lines containing a pattern ("find and replace")
        • example

          1 This ia the first line of an example text
          2 It is a text with erors
          3 Lots os erors
          4 So much erors, all these eros are making me sick.
          5 This is a line not containing any errors
          6 This is the last line.
        • sed  '/erors/p' example(search stringを含む行は2度出る)
        • matched pattern の乱すには-nをつける。 sed -n '/erors/p' example
      2. Deleting lines of input containing a pattern
        • sed '/erors/d' example (1,5,6行)
        • sed -n '/^This.*errors.$/p' example (5行)-- パターンで始まりパターンで終わる.
      3. range of lines
        • sed '2,4d' example (2-4行を取り去る)
        • sed '3,$d' example (3-終行を取り去る)
        • sed -n '/a text/, /a line/p' example (パターン:a text --> a lineを含む行まで、2、3、4、5行)
      4. find and replace with sed
        • sed 's/erors/errors/' example
        • sed 's/erors/errors/g' example (総て)
        • sed 's/^/> /' example
        • sed 's/$/EOL/' example
        • sed -e 's/erors/errors/g' -e 's/last/final/g' example (Multiple find and replace)
    3. Non-interactive editing

        1. reading sed commands from a file
          • -f option
          • line の最後にtrailing white space が在ってはならない。
          • quoteは使えない
          • 付加或いは置換するテキストは最終行を除いて、\で終わらせねばならない。
        2. writing output files
          • cat  script.sed
            1i\
            <html>\
            <head><title> Sed generated html </title></head>\
            <body bgcolor=#fffffff">\
            <pre>
            $a\
            </pre>\
            </body>\
            </html>
          • cat text2html.sh
            #!/bin/bash
            #
            #
            #

            echo "converting $1..."
            SCRIPT="/home/ouryouji/scripts/script.sed"
            NAME=$1
            TEMPFILE="/var/tmp/sed.$PID.tmp"
            sed "s/\n/^M/" $1 | sed -f $SCRIPT | sed "s/^M/\n/" > $TEMPFILE
            mv$TEMPFILE $NAME
            echo done
          • cat test
            line 1
            line 2
            line 3
          • txt2html.sh tst
  6. The GNU awk programming language

    1. getting started with gawk

      1. What is gawk
      2. gawk commnds
        • awk PROGRAM inputfile(s)
        • awk -f PROGRAM-FILE  inputfile(s)
    2. The print program

      1. print command がinput fileから選択されたデータを出力する.FSによってフィールドに分割して読み込む。$1,$2,... $Nが1,2,... N番目の値を持つ。$0は全ラインの値を持つ。ls -l | awk '{print $5 $8}'
      2. Formatting fields
        • ls -ldh * | grep -v total | awk '{print "Size is " $5 "bytes for " $8}'
        • df -h | sort -rnk5 | head -3 | awk '{print "Pattern" $6 "\t: "full!"}'
      3. The print command and regular expressions
        • awk 'EXPRESSION {PROGRAM}' file(s)
        • example : df -h | awk '/dev\/hda/ {print $6 "\t:" $5}'
        •                :ls -l | awk '/\<(a|x).*\.conf$/ {print $8}'
      4. special patterns
        • コメント先行させるためにBEGIN
          • ls -l | awk 'BEGIN {print "Fields found :\n"}' /\<[a|x].*\.conf$/ {print $8}
        • 入力プロセスが終わった後テキストを挿入するためEND
          • awk '/\<[a|x].*\.conf$/ { print $9 } END { print \	
            "Can I do anything else for you, mistress?" }'
      5. GAWK scripts
        • cat diskrep.awk

          BEGIN {print "***WARNING ASRNING WARNING***"}
          /\<[[8|9][0-9]%/ {print "Partition" $6 "\t: " $5 "full!"}
          END  {print "***Give money for new disks URGENTLY***"}

          df -h | awk -f diskrep.awkと実行
    3. Gawk variables

      1. input field separator
        • awk 'BEGIN {FS=":"}{print $1 "\t" $5}' /etc/passwd
      2. output  separator
        1. output field separator(OFS)
          • cat testawk

            record1   data1
            record2   data2
          • awk '{print  $1 $2}' testawk -> record1data1 ...(OFS 無視)
          • awk '{print $1,$2}' testawk --> record1 data1 ...
        2. output record separator(ORS)
          • プリント出力時のセパレータ
          • awk 'BEGIN{OFS=";"; "ORS"="\n-->\n"} {{print$1,$2}' testawk
      3. the number of records
        • builtin NR = processed record数(newlineを読めば増える)
        • cat processed.awk

          BEGIN {OFS="-"; ORS="\n--->done\n"}
          {print "record number" NR ":\t" $1,$2}
          END {print "Number of record processed: "NR}
           
        • awk -f processed.awk testawk
      4. Use defined variables
        • predefined でない変数は作られて初期化
        • cat revenues
          20021009  20021013  consultancy  BigComp    2500
          20021015  20021020  training         EduComp   2000
          20021112  20011123  appdev         SmartComp 1000
          20021204  20021215  training         EduComp   5000
        • cat total.awk

          {total=total+$5}
          {print "Send bill  for " $5 "dollar to $4"
          End {print"-----------\nTotal revenue: " total}
        • awk -f total.awk revenues
      5. More examples
        • cat make-html-from-text.awk

          BEGIN{print "<html>\n<head><title>Awk-generated HTML\
          </title></head>\n<body bgcolor=\"#ffffff\">\n<pre>"}
          {print $0}  
          END {print "</pre>\n</body>\</html>\"}
        • awk -f make-html-from-text.awk testfile >file.html
        • $0=全行
      6. The print program
        1. printf
  7. Conditional statement

    1. Introduction to if

      1. general
        • if TEST-COMMAND ;then CONSEQUENT-COMMANDS; fi
        1. Expression used with if
          • Primary expressions
          • [-a FILE]
            true if FILE exists
            [-b FILE]
            true if FILE exists and is a block-special file
            [-c FILE]
            true if FILE exists and is a character-special file
            [-d FILE]
            true if file exists and is a directory
            [-e FILE]
            true if FILE exists
            [-f FILE]
            true if FIL Eexists and is a regular file
            [-g FILE]
            true if FILE exists and its SGID bit is set
            [-h FILE]
            true if FILE exists and is a symbolic link
            [-k FILE]
            true if FILE exists and its sticky bit is set
            [-p FILE]
            true if FILE exists and is a named pipe(FIFO)
            [-r FILE]
            true if......and is readable
            [-s FILE]
            true if.......and has a size grater than 0
            [-t FD]

            [-u FILE]
            true if ......and its SUID(set user ID) bit is set
            [-w FILE]
            true if .......and is writable
            [-x FILE]
            true if .......and is executable
            [-O FILE]
            true if .......and is owned by the effective user ID
            [-G FILE]
            true if ........  ..............................effective group ID
            [-L FILE]
            true if.........and is a symbolic linc
            [-N FILE]
            true if .........and has been modified since it was last read
            [-S FILE]
            true if .........and is a socket
            [FILE1 -nt FILE2]

            [FILE1 -ot FILE2]

            [FILE1 -ef FILE2]

            [-o OPTIONNAME]
            true if shell option "OPTIONNAME" is enabled
            [-z STRING]
            true if  the  length of "STRING" is zero
            [-n STRING] or [STRING]
             true if the length of "STRING" is non-zero
            [STRING1==STRING2]

            [STRING1!=STRING2]

            [STRING1<STRING2]

            [STRING1>STRING2]

            [Arg1 OP Arg2]
            OPは-eq,-ne,-lt,-le,-gt,geの一つArg1,2ともinteger.
          • Operation
            Effect
            [!EXPR]
            true if EXPR is false
            [(EXPR)]
            EXPRの値を返す。opratorの通常の手続きに重ねうる。
            [EXPR1 -a EXPR2]
            both EXPR1 AND EXPR2 are trueの時真
            [EXPR1 -o EXPR2]
            either EXPR1 OR EXPR2 is true の時真
            t
        2. commandsfollowing the then statement
        3. checking files[msgcheck.sh]
          • #!/bin/bash
            echo "This script checks the existance of the message file"
            echo "checking..."
            if [-f /var/usr/log/messages]
              then
                echo "/var/log/message exists."
            fi
            echo
            echo "done"
        4. checking shell options
          • if [-o noclobber]
              then
                echo "Your files are protected against accidental overwriting using redirection"
            fi
      2. Simple application of it
        1. testing exit status
          • if [$? -eq 0]
              then echo 'That was a good job'
            fi
          • test commandはany unix command でも可

            if ! grep $USER /etc/passwd
              then echo "Your user account is not managed locally"; fi

            echo $?
            0
          • grep $USER /etc/passwd
            if [$? -ne 0]; then echo "not a local account" ;fi
        2. Numeric comparisons
          • num=`wc -l work.txt`
            echo $num => 201

            if [$num -gt 150]
              then echo ; echo "You've worked hard enough for today"
            echo; fii
          • cronで毎日曜日に実行されるプログラム

            #!/bin/bash
            #dateコマンドで週の数を計算
            WEEKOFFSET=$[$(date +%V")%2]
            #余りがなければ偶数週
            #メッセージ
            if [$WEEKOFFSET -eq "0"]; then
            echo "日曜夜ゴミ箱を開けよ" | mail -s "Garbage cans out"
        3. string comparisons
          • if ["$(whoami)]"!='root'; then
              echo "You have no permission to run $0 as non-root user."
              ; exit 1;
            fi
          • [ "$(whoami)" != 'root' ] && ( echo you are using a non-privileged account; exit 1 )
          • test "$(whoami)" != 'root' && (echo you are using a non-privileged account; exit 1)
          • gender="female"
             
            if [[ "$gender"== f* ]]
            rhen echo  "Pleasure to meet you, Madame."; fi
            (regular expression も)
    2. More advanced if usage
      1. if /then/else constructs
        1. Dummy example
          • gender=="male"
            if [[ "$gender"== f* ]]
            then echo "pleasure to meet you,Madam."
            else echo  "How comr the lady hasn't got a drink yet?"
            fi

            [[ は変数値のsplitting とpathname expansionを抑える。
          • su -
            # if ! grep ^$user /etc/passward 1> /dev/null
            then echo "your user account is not managed locally
            else echo "your account is managed from the local /etc/password file"
            fi
        2. checking command line arguments
          • 変数の値をコマンドラインから入力する法がエレガントで、positional parameter $1,$2,...$Nを使う。
          • $#はコマンドライン引数の数、$0はスクリプト名である。
          • cat penguin.sh
            #!/bin/bash
            #This script lets you present different menus to Tux, He'll only be happy when given a fish
            if [ "$1" == fish ];
            then
              echo "HMMMM fish... Tux happy!"
            else
              echo "Tux don't like that .Tux wants fish!"
            fi

            penguin.sh apple etc
          • cat weight.sh
            #!/bin/bash
            # This script prints a message about your weight
            weight="$1"
            height="$2"
            idealweight= $[ $height - 110]
            if [ $weight -lt $idealweight ]; then
            echo " you should eat a bit more fat"
            else
            echo "You should eat a bit more fruit"
            fi

            bash -x weight.sh 55 169
        3. testing the number of arguments
          • cat weight.sh
            #!/bin/bash
            # This script prints a mesage about your weight if you give it your
            # weight in kilos and height in centimeters
            if [ ! $# == 2 ]; then
              echo "Usage: $0 weight_in_kilos length_in_centimeters"
              exit
            fi
            weight="$1"
            height = "$2"
            以下仝

            引数が2以外ならエラー
        4. Testing that a file exists
          • #!/bin/bash

            # This script gives information about a file.

            FILENAME="$1"

            echo "Properties for $FILENAME:"

            if [ -f $FILENAME ]; then
            echo "Size is $(ls -lh $FILENAME | awk '{ print $5 }')"
            echo "Type is $(file $FILENAME | cut -d":" -f2 -)"
            echo "Inode number is $(ls -i $FILENAME | cut -d" " -f1 -)"
            echo "$(df -h $FILENAME | grep -v Mounted | awk '{ print "On",$1", \
            which is mounted as the",$6,"partition."}')"
            else
            echo "File does not exist."
            fi
          • ls -lh (long,human-radable):
          • 例 file processed.awk -> processed.awk:ASCII text(f2である)
          • cut は与えられたファイルそれぞれから各行の一部を選択して標準出力に書き出す。
            • ファイルが1つもないと標準入力から、ファイルが'-'だったら標準入力が用いられる.
            • cut -d(delim:区切り)":" -f2(フィールド)
            • cut -d" " -f2 - として ouryouji yukito (ENTER) >yukito ..と無限に続く。
          • df -h (各ファイルがその上にあるファイルシステムの情報或いは全ファイルシステムの情報)
            • => Filesystem Size Used Avail Use% Mountedon だから ($1は/dev/hda2 $6は/  )
      2. if/then/elif/else costructs
        1. general
          • 例(crontabに入れて毎日実行できる) 
             /etc/cron.daily> cat disktest.sh
            #!/bin/bash
            # This script does a very simple test for checking disk space
            space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f 1 -`
            altervalue=80
            if ["$space" -ge "$altervalue"] ; then
            echo "At last one of my disks is nealy full! | mail -s "daily disk check" root
            else
            echo "disk space normal "| mail -s "daily diskcheck" root
            fi
      3. Nested if statement
        1. cat testleap.sh
          • #!/bin/bash
            # This script will test if we're in the leap year or not
            year=`date +%Y`
            if [$[$year %400] -eq "0"]; then
              echo "This is a leap year . February has 29 days."
            elf [$[$year %4] -eq "0"; then
              if [$[$year %100] -ne 0]; then
                echo "This is a leap year , February has 29 days."
              else
                 echo "This is not a leap year , February has 28 days."
             fi
            else
              echo "This is not a leap year, February has 28 days."
            fi
      4. Boolean opearations
        • 上記のスクリプトは"AND"(&&)と”OR”(||)で短縮できる。
        • year=`date +%Y`
          if (( ("$year" %400) == "0" )) || (( ("$year" %4 =="0") && ("$year %100 !="0") ))
          echo "This is a leap year...
          else
          echo "This is not a leap year."
          fi
        • 数学expression test には(( double bracket を用いる。[[では働かない。
      5. Using the exit statement and if
        • exit statementは引数を取り親にパスされ、$?にストアされる。0が成功。
        • 例 cat penguin.sh
        • #!/bin/bash
          # This script lets you present different menus to Tux. He
          # will only be happy when givena fish. We've also added a
          # dorphin and (prsumably)  a camel.
          if ["$menu"=="fish" ] ;then
            if ["$animal"=="penguin"] ; then
              echo "Humm fish... Tux happy!"
            elif ["$animal"=="dolphin"]; then
              echo "Pweetpeet...!"
            else
              echo "*prrrr   t*"
            fi
          else
            if [ "$animal" =="penguin" ;then
              echo "Tux does'nt like that. Tux wants fish!"
              exit 1
            elif [ "$animal"=="dolphin"] ; then
              echo "Pweepwish........... "
              exit 2
            else
              echo"Will you read this sign?!"
              exit 3
            fi
          fi

          このスクリプトはfeed.shから呼ばれる.

        • cat feed.sh
        • #!/bin/bash
          # This script acts upon the exit status given by pehguin.sh
          export menu="$1"
          export animal="$2"
          feed="/home/ouryouji/scripts/penguin.sh"
          $feed $menu $animal
          case $? in
          1)
            echo "guard:You'd better give'n a fish, less they get violent"
            ;;
          2)
            echo "Guard : It's because of people like you that they are leaving earth all the time."
            ;;
          3)
            echo "Guard: By the food that the zoo provide for the animals, you***,how do you think we survive?"
            ;;
          *)
            echo "Guard; Don't forget the guide!"
            ;;
          esac


    3. Using case statement

      1. simplified conditions
        • Nested i fは混乱しやすい。case expression case1) command-list;; case2) command-list;; ...;; esac
        • ”|”はmulti patternを分けるのに使い”)”はpatern list をおわらせるのに使う。
        • 各case + commandはclauseと呼ばれ";;"で終わらねばならない。
        • cat disktest.sh
        • #!/bin/bash
          # This script does a very simple test for checking disk space
          space=`df -h | awk '{print $5}' | grep %| grep -v Use | sort -n | tail -1 | cut -d"%" -f1 -`
          case $space in
          [1-6]*)
            Message="All is quiet."
            ;;
          [7-8]*)
            Message="Start thinking cleaning out some stuff"
            ;;
          9[1-8]*
            Message="Better hurry with that new disk...
            ;;
          99)
            Message="I'm drawning here!"
            ;;
          *)
            Message="I seem to be running with an unexixtent amount of disk space .."
            ;;
          esac
          echo $Message | mail -s "dik report `date`" ouryouji

          You have new mail が実行結果(/var/spool/mail/ouryouji) subject : disk report

      2. Initscript example
        • case "$1" in
              start)
                start
                ;;
              stop)
                stop
                ;;
              status)
                status anacron
                ;;
              restart)
                stop
                start
                ;;
              condrestart)
                if test "x`pidof anacron`" | =x; then
                    stop
                    start
               fi
               ;;
              *)
                echo $"Usage : $0{start | stop | restart | condrestart | status}"
                exit
          esac
  8. Writing inteactive scripts

    1. Displaying user messages

      1. interactive or not?
      2. Using the echo built-in command
        • echoはその引数を出力return statusは常に0である。2つのオプションがある。
          • -e: backslash escape文字を訳す。
          • -n: trailing newline をsuppress
        • #!/bin/bash

          # This script lets you present different menus to Tux. He will only be happy
          # when given a fish. To make it more fun, we added a couple more animals.

          if [ "$menu" == "fish" ]; then
          if [ "$animal" == "penguin" ]; then
          echo -e "Hmmmmmm fish... Tux happy!\n"
          elif [ "$animal" == "dolphin" ]; then
          echo -e "\a\a\aPweetpeettreetppeterdepweet!\a\a\a\n"
          else
          echo -e "*prrrrrrrt*\n"
          fi
          else
          if [ "$animal" == "penguin" ]; then
          echo -e "Tux don't like that. Tux wants fish!\n"
          exit 1
          elif [ "$animal" == "dolphin" ]; then
          echo -e "\a\a\a\a\a\aPweepwishpeeterdepweet!\a\a\a"
          exit 2
          else
          echo -e "Will you read this sign?! Don't feed the "$animal"s!\n"
          exit 3
          fi
          fi

          michel ~/test> cat feed.sh
          #!/bin/bash
          # This script acts upon the exit status given by penguin.sh

          if [ "$#" != "2" ]; then
          echo -e "Usage of the feed script:\t$0 food-on-menu animal-name\n"
          exit 1
          else

          export menu="$1"
          export animal="$2"

          echo -e "Feeding $menu to $animal...\n"

          feed="/nethome/anny/testdir/penguin.sh"

          $feed $menu $animal

          result="$?"

          echo -e "Done feeding.\n"

          case "$result" in

          1)
          echo -e "Guard: \"You'd better give'm a fish, less they get violent...\"\n"
          ;;
          2)
          echo -e "Guard: \"No wonder they flee our planet...\"\n"
          ;;
          3)
          echo -e "Guard: \"Buy the food that the Zoo provides at the entry, you ***\"\n"
          echo -e "Guard: \"You want to poison them, do you?\"\n"
          ;;
          *)
          echo -e "Guard: \"Don't forget the guide!\"\n"
          ;;
          esac

          fi

          echo "Leaving..."
          echo -e "\a\a\aThanks for visiting the Zoo, hope to see you again soon!\n"

          michel ~/test> feed.sh apple camel
          Feeding apple to camel...

          Will you read this sign?! Don't feed the camels!

          Done feeding.

          Guard: "Buy the food that the Zoo provides at the entry, you ***"

          Guard: "You want to poison them, do you?"

          Leaving...
          Thanks for visiting the Zoo, hope to see you again soon!

          michel ~/test> feed.sh apple
          Usage of the feed script: ./feed.sh food-on-menu animal-name

    2. catching user

      1. Using the read built-in command
        • echoとprintfのconterpart?
        • read [options] NAME1 NAME2 ... NAMEN from standard input or file descriptor(-u optionをつけて、引数として)
          • 行の最初の語=NAME1,次はNAME2...,残余のwods+separatorをlast name NAMENと割り当てる。
          • NAMEより少ない語が読まれたら、残ったnamesにはempty valuesを割り当てる。
          • OptionMeaning
            -a ANAMEwordsはindexゼロで始まる配列変数ANAMEに割り当てられる.array=(
            -d DELIM入力の区切りをnewlineではなくdelimitatorとする。
            -ereadline is used to obtain the line.
            -n NCHARSn characters をよむ。
            -p PROMPTプロンプトを表示し端末から入力
            -r\をエスケープとして使わない.
            -sSilent mode.
            -t TIMEOUTCause read to time out and return failure if a complete line of input is not read within TIMEOUT seconds. This option has no effect if read is not reading input from the terminal or from a pipe.
            -u FDRead input from file descriptor FD.
        • 例: cat leaptest.sh
        • #!/bin/bash
          # This script will test if you have given a leap year or not.
          echo "Type the year that you want to check(4digits), follwed by [ENTER]:"
          read year
          if (( ("$year" %400) == "0")) || (( ("$year" %4 =="0") && ("$year" %100 != "0") )); then
          echo "$year" is a leap year."
          else
          echo "This is not a leap year."
          fi

          leaptest.shで実行
      2. Prompting for user input.
        • cat friends.sh
        • #!/bin/bash
          # This is a program that keeps your address book up to date.
          friends=/var/tmp/ouryouji/friends
          echo "Hello, "$USER". This script will register you in ouryouji's friends database."
          echo -n "Enter your name and press [ENTER]:"
          read  name
          echo "Enter your gender and press [ENTER]:"
          read -n 1 gender
          echo
          grep -i "$name" "$friends"
          if ["$?" == 0] ; then
              echo "You are already registered, quitting."
              exit 1
           elif ["$gen der" =="m"] ; then
              echo "You are added to ouryouji's friends list."
              exit 1
           else
              echo -n "How old are you?"
              read age
              if ["$age -lt 25 ] ;then
               echo -n "Which colour of hair do you have?"
              read colour
              echo "$name $age $colour" >> "$friends"
              echo "You are added to ouryouji's friends list"
              exit 1
           fi
          fi

          cp friends.sh /var/tmp; cd /var/tmp
          touch friends ; chmod a+w friends
           
      3. Redirection and file descriptors
        1. general
          • command input & output は実行前にredirectされうる.(ファイルのopen close ,script中にも可)
          • ファイルのI/Oはinteger handles(file descriptors)で達成される;stdin(0), stdout(1),stderra(2) これはreserved
          • 上記fdが実際のデバイスをどう指すか
          • michel ~> ls -l /dev/std*
            lrwxrwxrwx 1 root root 17 Oct 2 07:46 /dev/stderr -> ../proc/self/fd/2
            lrwxrwxrwx 1 root root 17 Oct 2 07:46 /dev/stdin -> ../proc/self/fd/0
            lrwxrwxrwx 1 root root 17 Oct 2 07:46 /dev/stdout -> ../proc/self/fd/1

            michel ~> ls -l /proc/self/fd/[0-2]
            lrwx------ 1 michel michel 64 Jan 23 12:11 /proc/self/fd/0 -> /dev/pts/6
            lrwx------ 1 michel michel 64 Jan 23 12:11 /proc/self/fd/1 -> /dev/pts/6
            lrwx------ 1 michel michel 64 Jan 23 12:11 /proc/self/fd/2 -> /dev/pts/6
            • 各プロセスは/proc/self(/proc/<process_ID>のsymbolic link)下にfileのviewを持つ
          • コマンド実行時以下のステップがこの順に実行される
            • 標準出力やコマンドが標準入力にパイプされると/proc/<current_process_ID>/fd/0が/proc/<process_ID>/fd/1と同じ無名のパイプをターゲットとするようにupdateされる。
            • 標準出力やコマンドが次のコマンドのstandard inputとパイプされると/proc/<current_process_ID>/fd/1が他の無名パイプをtargetとするようにupdateされる。
            • 現コマンドのredirectionは左ー>右へプロセスされる
            • N>&M or N<&M redirectionは /proc/self/fd/Nのsym.linkを/proc/self/fd/Mのsym.linkにupdarte する
            • redirection "N> file"と"N< file"は/proc/self/fd/Nを当該ファイルと同じsym.linkとする
            • N>&-は/proc/self/fd/Nというsym.linkを削除する。

          • コマンドラインよりスクリプトを実行するとき同じ(patrentの)file descriptorが子プロセスに使われるから何事も起こったように見えない。
          • cron使用時のように親が使われていないときstandard file descriptor はpipeか他の一時ファイルになる。(at scriptから)
            • at ..
              at > ls -l /proc/self/fd/ > /var/tmp/fdtest.at
              at > <EOT> (Ctrl+Dのこと)
              cat /var/tmp/fdtest.at

              lr-x.....   0 -> /var/spool/cron/at jobs (入力)
                   1  /var/tmp/fdtest.at         (出力)
                   2 /var/       (エラー)
                   3 
        2. Redirection of errors(本と違うがーーー)
          • 入出力ファイルをスクリプト用に支給できるがredirection errorsがよく忘れられる(mailで届けば幸運)
          • エラーをredirect する時 order of precedenceが重要(例: /var/spool中で)
            • ls -l *  2> /var/tmp/unaccesible-in-spoolはlsのエラーをこのファイルに出力。outputはstdoutに
            • ls -l * > /var/tmp/spoollist 2>&1 はstandard inputとstandard errorをspoollistにdirect
            • ls -l * 2>&1 > /var/tmp/spoollistはstandard outputを行き先ファイルに出力。standard errorはstandard outputに(standard outputが出力される前に)コピーされる。
            • BASHは標準出力と標準エラー両者をファイルに &> FILE という形でredirectできる(> FILE 2>&1 と同じ)
      4. File input and output
        1. Using  /dev/fd
          • /dev/fd/N はfile descriptor N と同じ(/dev/stdin,/dev/stdout, /dev/stderr =>/dev/fd0,/dev/fd1,/dev/fd2)
          • /dev/fd/ filesはシェルで主に使われ、pathname引数が標準入力、標準出力を(他のpathnameと同様に)使う。/dev/fdがシステムで使えない場合-を使ってパイプを読むことでバイパスする.
            • 例 :filter body.txt,gz | cat header.txt - footer.txt(-:パイプから読め)
              • catでまずfile header.txt,つぎにそのstandard inputがfilterの出力、最後にfooter.txtを読む。
              • -のspecial meaning(standard input or output)--多くのプログラムでのmisconception, /dev/fdが混乱を避ける。
              • filter body.txt | cat header.txt /dev/fd/0 footer.txt | lp
        2. Read and exec
          1. Assigning file descriptors to files
            • exec fdN> fileは(file descriptor )N をfile名代わりに (出力用に)割り当てる.(画面はN=file)
            • また exec fdN< fileは(file descriptor) Nを file名代わりに(入力用に)に使う。(キーボードはN=file)
            • file desriptor がfileに割当てられた後shell redirection operatorとして使われる.
            • exec 4> result.txt
              filter body.txt | cat header.txt /dev/fd0 footer.txt >& 4
              cat result.txt

              4をresult.txt(出力用)に。file4にcat結果をinput.このoutputがresut.txt. result.txtをcat
            • 5は使ってはならない。
          2. Read in scripts
            •    cat sysnotes.sh
              #!/bin/bash

              # This script makes an index of important config files, puts them together in
              # a backup file and allows for adding comment for each file.

              CONFIG=/var/tmp/sysconfig.out
              rm "$CONFIG" 2>/dev/null

              echo "Output will be saved in $CONFIG."

              # create fd 7 with same target as fd 0 (save stdin "value"):7を標準入力と同じに
              exec 7<&0

              # update fd 0 to target file /etc/passwd:標準入力を/etc/passwd
              exec < /etc/passwd

              # Read the first line of /etc/passwd
              read rootpasswd

              echo "Saving root account info..."
              echo "Your root account info:" >> "$CONFIG"
              echo $rootpasswd >> "$CONFIG"

              # update fd 0 to target fd 7 target (old fd 0 target); delete fd 7:標準入力を7(以前の標準入力)
              exec 0<&7 7<&-

              echo -n "Enter comment or [ENTER] for no comment: "
              read comment; echo $comment >> "$CONFIG"

              echo "Saving hosts information..."

              # first prepare a hosts file not containing any comments
              TEMP="/var/tmp/hosts.tmp"
              cat /etc/hosts | grep -v "^#" > "$TEMP"

              exec 7<&0
              exec < "$TEMP"

              read ip1 name1 alias1
              read ip2 name2 alias2

              echo "Your local host configuration:" >> "$CONFIG"

              echo "$ip1 $name1 $alias1" >> "$CONFIG"
              echo "$ip2 $name2 $alias2" >> "$CONFIG"

              exec 0<&7 7<&-

              echo -n "Enter comment or [ENTER] for no comment: "
              read comment; echo $comment >> "$CONFIG"
              rm "$TEMP"
              ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
              michel ~/testdir> sysnotes.sh
              Output will be saved in /var/tmp/sysconfig.out.
              Saving root account info...
              Enter comment or [ENTER] for no comment: hint for password: blue lagoon
              Saving hosts information...
              Enter comment or [ENTER] for no comment: in central DNS

              michel ~/testdir> cat /var/tmp/sysconfig.out
              Your root account info:
              root:x:0:0:root:/root:/bin/bash
              hint for password: blue lagoon
              Your local host configuration:
              127.0.0.1 localhost.localdomain localhost
              192.168.42.1 tintagel.kingarthur.com tintagel
              in central DNS

          3. closing file descriptors
            • exec fd<&- :上の例では(7が標準入力に使われていたが)ユーザーがキーボードで入力する必要がある度に閉じる。
            • michel ~> cat listdirs.sh
              #!/bin/bash

              # This script prints standard output unchanged, while standard error is
              # redirected for processing by awk.

              INPUTDIR="$1"

              # fd 6 targets fd 1 target (console out) in current shell(6を標準出力に)
              exec 6>&1

              # fd 1 targets pipe, fd 2 targets fd 1 target (pipe),(1をパイプに、2を1の標的に(パイプ)
              # fd 1 targets fd 6 target (console out), fd 6 closed, execute ls(1を6の標的に(画面)、6閉じlsを実行)
              ls "$INPUTDIR"/* 2>&1 >&6 6>&- \
              # Closes fd 6 for awk, but not for ls.

              | awk 'BEGIN { FS=":" } { print "YOU HAVE NO ACCESS TO" $2 }' 6>&-

              # fd 6 closed for current shell
              exec 6>&-
          4. Here documents
            • 現ソースからinput を読む
            • cat startsurf.sh
            • #!/bin/bash
              # This script provides an easy way for users to choose between browsers
              echo "These are the web browsers on this system."
              # Start here document
              cat << BROWSERS
              mozilla
              links
              Konquaror
              lynx
              opera
              netscape
              BROWSERS
              # End here document
              echo -n "Which is your favorite?"
              read browser
              echo "Starting $browser, please wait..."
              $browser &

              michel ~> startsurf.sh
              These are the web browsers on this system:
              mozilla
              links
              lynx
              konqueror
              opera
              netscape
              Which is your favorite? opera
              Starting opera, please wait...

            • cat installs.sh
              #!/bin/bash
              # This script installs packages autimacally using yum
              if [$# -lt 1] ; then
                    echo "Usage:  $0 package"
                    exit 1
              fi
              yum install $1 << CONFIRM
              y
              CONFIRM
  9. Repetitive tasks

    1. The for loop

      1. how does it work
        • for NAME [in LIST]; do COMMANDS; done
        • [in LIST]が無ければin $@に代わり各positional parameterについてcomand実行
        • NAMEは変数名(iがよく使われる)
      2. Examples
        1. LISTアイテムを特定するためのコマンド置換
          • carol@octarine ~/articles] ls *.xml
            file1.xml file2.xml file3.xml

            [carol@octarine ~/articles] ls *.xml > list

            [carol@octarine ~/articles] for i in `cat list`; do cp "$i" "$i".bak ; done

            [carol@octarine ~/articles] ls *.xml*
            file1.xml file1.xml.bak file2.xml file2.xml.bak file3.xml file3.xml.bak
          • for i in `ls /sbin`; do file /sbin/$i | grep ASCII; done ..sbin中のテキストファイルをリスト(多分スクリプト)
        2. 変数の内容をリストアイテム特定に使う
          • htmi -> phpにあたって
            最初の25行と最後の21行を取り去りこれを2つのphp tags, header and footerで置き換える。
            beginfile と endfile は別途作成。

            [carol@octarine ~/html]
            cat html2php.sh
            #!/bin/bash
            # specific conversion script for my html files to php
            LIST="$(ls *.html)"
            for i in "$LIST"; do
            NEWNAME=$(ls "$i" | sed -e 's/html/php/')
            cat beginfile > "$NEWNAME"
            cat "$i" | sed -e '1,25d' | tac | sed -e '1,21d'| tac >> "$NEWNAME"
            cat endfile >> "$NEWNAME"
            done
    2. The while loop

      1. What is it?
        • WHILE CONTROLL COMMAND: do CONSEQUENT COMMANDS :done
      2. Examples
        1. simple
          • #!/bin/bash
            # This script opens 4 terminal windows.
              i="0"
              while [$i -lt 4]
              do
              xterm &
              i=$[$i+1]
              done
        2. nested
          • cat webcamcopy.sh
            #!/bin/bash
            # This script copies files from my home directory into the webserver directory
            # (use scp and ssh keys for a remote directory)
            # A new directory  is created every  hour.
            PICTDIR=/home/ouryouji/pics
            WEBDIR=/var/www/ouryouji/webcam
            while  true;  do
                DATE=`date +%Y%m%d`
                HOUR=`date +%H`
                mkdir $WEBDIR/"$DATE"
                while [$HOUR -ne "00"] ; do
                  DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
                  mkdir "$DESTDIR"
                  mv $PICTDIR/*.jpeg "$DESTDIR"/
                  sleep 3600
                  HOUR=`date +%H`
                  done
            done

            true statement は強制終了されるまで実行しつづけることを意味する

            これはsimulation testing用(ファイル生成)
            #!/bin/bash

            # This generates a file every 5 minutes

            while true; do
            touch pic-`date +%s`.jpg
            sleep 300
            done


        3. Using keybord input to control the while loop
          • wisdom.sh このスクリプトはCtrl+cでインタラプトされる
          • #!/bin/bash
            # This script provides wisdom
            FORTUNE=/usr/games/fortune
            while true ; do
            echo "On which topic do you want advice?"
            cat << topics
            politics
            startreck
            kernelnewbies
            sports
            bofh-excuses
            magic
            love
            literature
            drugs
            education
            topics

            echo
            echo "Free advice  on the topic of $topics:"
            echo
            $FORTUNE $topic
            echo
            done

            here documentが選択に使われtrue testがconsequent command listを繰り返す。
        4. calculating an average(average.sh)
          • #!/bin/bash
            # Calculate the average of a series of numbers
            SCORE="0"
            AVERATGE="0"
            SUM="0"
            NUM="0"
            while true ; do
                echo -n "Enter your score [0-100%]('q' for quit):"; read SCORE;
                if (("$SCORE" <  "0"))  ||  (("$SCORE" > "100" )) ; then
                  echo "Be serious . Common, try again
                elif [$SCORE" == "q"] ; then
                  echo "Average rating; $AVERAGE%."
                  break
                else
                  SUM=$[$SUM + $SCORE]
                  NUM=$ [$NUM + 1]
                  AVERAGE = $ [ $SUM / $NUM]
                fi
            done
            echo "Exiting"

            最後の行の変数は算術のためにクォートしてない事に注意
      3. The until loop

        1. what is it..
          • until TEST-COMMAND ; do CONSEQUENT COMMANDS; done
        2. example
          • improved picturesort.sh
          • #!/bin/bash

            # This script copies files from my homedirectory into the webserver directory.
            # A new directory is created every hour.
            # If the pics are taking up too much space, the oldest are removed.

            while true; do
            DISKFUL=$(df -h $WEBDIR | grep -v File | awk '{print $5 }' | cut -d "%" -f1 -)

            until [ $DISKFUL -ge "90" ]; do

            DATE=`date +%Y%m%d`
            HOUR=`date +%H`
            mkdir $WEBDIR/"$DATE"

            while [ $HOUR -ne "00" ]; do
            DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
            mkdir "$DESTDIR"
            mv $PICDIR/*.jpg "$DESTDIR"/
            sleep 3600
            HOUR=`date +%H`
            done

            DISKFULL=$(df -h $WEBDIR | grep -v File | awk '{ print $5 }' | cut -d "%" -f1 -)
            done

            TOREMOVE=$(find $WEBDIR -type d -a -mtime +30)
            for i in $TOREMOVE; do
            rm -rf "$i";
            done

            done
      4. I/O redirection and loops

        1. Input redirection
          • while TEST-COMMAND; do CONSEQUENT-COMMANDS; doneの後に command(よく使われるのはread) < file(loopをcontrolする)
        2. Output redirection
          • cat archive_old_stuff.sh
          • #!/bin/bash
            # This script creates a subdirectory in the current directory,
            # to which old files are moved.
            # might be something for cron (if slightly adapted) to execute
            # weekly or monthly
            ARCHIVER=`date +%Y%m%d`
            DESTDIR="$PWD/archive-$ARCHIVER"

            mkdir "$DESTDIR"
            # using quotes to catch file names containing spaces,using read -d for more
            # fool-proof usage
            find $PWD -type f -a -mtime +5 | while read -d $'\000' file #デリミタがこれというのが分からない
            do
            gzip "$file" ; mv "$file.gz" "$DESTDIR"
            echo "file archived"
            done
      5. break and continue
        1. The break built-in
          • improved version of wisdom.sh
          • #!/bin/bash
            # This script provides a wisdom
            # You can now exit in a descent way
            FORTUNE=/usr/games/fortune
            while true ; do
            echo "On which topic do you want to advice?
            echo "1.politics
            echo "2. startrek"
            echo "3. kernelnewbies"
            echo "4. sports"
            echo "5. bofh-excusec"
            echo "6. magic"
            echo "7. love"
            echo "8. literature"
            echo "9. drugs"
            echo "10. education"
            echo
            echo -n "Enter your choice, or 0 for exit"
            read choice
            echo
            case $choice in
            1)
            $ FORTUNE politics
            ;;
            2)
            $FORTUNE srartrek
            ;;
            3)
            $FORTUNE kernelnewbies
            ;;
            4)
            echo "Sports are a waste of time, energy and money."
            echo "Go back to your keyword."
            echo -e "\t\t\t...\"Unhealthy is my middle name\"Soggie"
            ;;
            5)
            $FORTUNE bufh-excuses
            ;;
            6)
            $FORTUNE magic
            ;;
            7)
            $FORTUNE love
            ;;
            8)
            $FORTUNE literature
            ;;
            9)
            $FORTUNE drugs
            ;;
            10)
            $FORTUNE education
            ;;
            0)
            echo "OK. see you!"
            break    # exit the loop not the script
            ;;
            *)
            echo "That is not a valid choice, try a number from 0 to 10."
            ;;
            esac
            done
        2. The continue built-in
          • resume iteration (for, while, until,or select)
          • #!/bin/bash
            # This script converts all file names containing upper case characters into file# names containing only lower cases
            LIST="$(ls)"
            for name in "LIST" ; do
            if [["$name"!=*[[:upper:]]*]]; then
            continue
            fi
            ORIG="$name"
            NEW=`echo $name | tr 'A-Z' 'a-z'`
            mv "$ORIG" "NEW"
            echo "new name for $ORIG is $NEW"
            done

      6. Making menus with the select built-in
        1. General
          1. Use of select (for loopと同じような文法)
              • select WORD [in LIST]; do RESPECTIVE-COMMANDS; done
              • もし[in LIST]がなかったらin$@が決められていたかのようにpositional paramerがprintされる、
            • private.sh
              #!/bin/bash
              echo "This script can make any of the file in  this directory private."
              echo "Enter the number of the file you want to protect:"
              select FILENAME in  *;
              do
                  echo "You picked $ FILENAME($REPLY),  it is now only accessible to you."
                  chmod go-rwx "$FILENAME"
              done
            • #!/bin/bash

              echo "This script can make any of the files in this directory private."
              echo "Enter the number of the file you want to protect:"

              PS3="Your choice: "
              QUIT="QUIT THIS PROGRAM - I feel safe now."
              touch "$QUIT"

              select FILENAME in *;
              do
              case $FILENAME in
              "$QUIT")
              echo "Exiting."
              break
              ;;
              *)
              echo "You picked $FILENAME ($REPLY)"
              chmod go-rwx "$FILENAME"
              ;;
              esac
              done
              rm "$QUIT"

        2. submenus
      7. The shift built-in
        • こ のコマンドは1つの引数(N)をとる。positional parameters はN+1~$#が$1~$#ーN+1にrenameされる。10の引数を取るコマンドでNが4なら$4が$1に$5が$2に…(この説明が正しいか?)。 n=0か$#より大きいなら無変化。
        • cleanup.sh
          #!/bin/bash
          # This script can clean up files that were last accessed over 365 days ago
          USAGE="Usage: $0 dir1 dir2 dir3... dirN"
          if [ "$#" == "0" ] ; then
              echo "$USAGE"
              exit 1
          fi
          while (( "$#" )); do
          if [[ $(ls "$1" )) == ""]] ; then
              echo "Empty directory, nothing to be done."
          else
              find "$1" -type f -a -atime +365 -exec rm -i {} \;
          fi
          shift
          done

  10. More on variables

    1. types of variables

      1. General assignment values
      2. Using the declare built-in
        • OptionMeaning
          -aVariable is an array.
          -fUse function names only.
          -iThe variable is to be treated as an integer; arithmetic evaluation is performed when the variable is assigned a value
          -pDisplay the attributes and values of each variable. When -p is used, additional options are ignored.
          -rMake variables read-only. These variables cannot then be assigned values by subsequent assignment statements, nor can they be unset.
          -tGive each variable the trace attribute.
          -xMark each variable for export to subsequent commands via the environment.
        • [bob in ~] declare -i VARIABLE=12

          [bob in ~] VARIABLE=string

          [bob in ~] echo $VARIABLE
          0

          [bob in ~] declare -p VARIABLE
          declare -i VARIABLE="0"
      3. constants
        1. readonly OPTION VSRIABLE(s)という文法で作る。
          • -fオプションで各変数はshell functionを引用
          • -aオプションで各変数は配列を引用
          • 引数なし或いは-pオプションで全read-only variablesが表示される.
    2. array variables

      1. creating arrays
        • ARRAY[INDEXNR]
        • declare -a ARRAYNAME
        • ARRAY=(val1 val2 ... valN)








ouryouzi.myvnc.com/yukito
2