读书笔记 - Beginning Linux Programming - Chapter 2 Shell Programming

    技术2022-05-20  31

    Shell

     

    What is Shell

    Just like the batch file in windows, but more powerful

     

    Pipes and redirection

     

    Redirecting Output

    $ ls -l > lsoutput.txt

    Write into isoutput.txt $ ps >> lsoutput.txt

    Append to the file

    $ kill -HUP 1234 >killout.txt 2>killerr.txt Kill the process and sperate the output and error info into different files

    $ kill -1 1234 >killouterr.txt 2>&1

    Kill the process and write the error info in to the same file as output

     

    Redirecting Input

    $ more < killout.txt

     

    Pipes

    You can connect processes using the pipe operator ( | ).In Linux, unlike in MS-DOS, processes connected by pipes can run simultaneously and are automatically rescheduled as data flows between them $ ps | sort > pssort.out $ ps | sort | more $ ps –xo comm | sort | uniq | grep -v sh | more

     

    The Shell as a Programming Language

    $ for file in * > do > if grep -l POSIX $file > then > more $file > fi > done Note how the normal $ shell prompt changes to a > when the shell is expecting further input. You can type away, letting the shell decide when you’re finished, and the script will execute immediately.

     

    widl cards

    $ ls my_{finger,toe}s

     

    Experienced Linux users would probably perform this simple operation in a much more efficient way, perhaps with a command such as $ more `grep -l POSIX *` or the synonymous construction $ more $(grep -l POSIX *) In addition, $ grep -l POSIX * | more

     

    Creating a script

    #!/bin/sh #first #This file looks through all the files in the current #directory for the string POSIX, and then prints the names of t#hose files to the standard output. for file in * do if grep -q POSIX $file then echo $file fi done exit 0

     

    #! characters tell the system that the argument that follows on the line is the program to be used to execute this file. In this case, /bin/sh is the default shell program.

     

    The exit command ensures that the script returns a sensible exit code

     

    Lnux, and UNIX in general, rarely makes use of the filename extension to determine the type of a file

     

    Making a script executable

     

    1. $ /bin/sh first

    2. $ chmod +x first

    #cp first /usr/local/bin #chown root /usr/local/bin/first #chgrp root /usr/local/bin/first #chmod 755 /usr/local/bin/first

     

    Shell Syntax

     

    Varaibles

    You don’t usually declare variables in the shell before using them. Instead, you create them by simply using them (for example, when you assign an initial value to them). By default, all variables are consid- ered and stored as strings, even when they are assigned numeric values. The shell and some utilities will convert numeric strings to their values in order to operate on them as required. Linux is a case-sensitive system, so the shell considers the variable foo to be different from Foo, and both to be different from FOO.

     

    $ salutation=Hello $ echo $salutation Hello $ salutation=”Yes Dear” $ echo $salutation Yes Dear $ salutation=7+5 $ echo $salutation 7+5

     

    Note how a string must be delimited by quote marks if it contains spaces. In addition, there can’t be any spaces on either side of the equals sign.

     

    $ read salutation Wie geht’s? $ echo $salutation Wie geht’s?

     

    The behavior of variables such as $foo inside quotes depends on the type of quotes you use. If you enclose a $ variable expression in double quotes, then it’s replaced with its value when the line is exe- cuted. If you enclose it in single quotes, then no substitution takes place. You can also remove the special meaning of the $ symbol by prefacing it with a /.

     

    #!/bin/sh myvar=”Hi there” echo $myvar echo “$myvar” echo ‘$myvar’ echo /$myvar echo Enter some text read myvar echo ‘$myvar’ now equals $myvar exit 0

    Enrironment Varaible

    $HOME $PATH $PS1 $PS2

    $IFS $0 $# $$

     

    Parameter Variable

    $1,$2,$3

     

    Conditions

    The test and [ commond

    In practice, most scripts make extensive use of the [ or test command, the shell’s Boolean check

     

    if test -f fred.c then ... fi

     

    if [ -f fred.c ] then ... fi

     

    Note that you must put spaces between the [ braces and the condition being checked. You can remember this by remembering that [ is just the same as writing test, and you would always leave a space after the test command. If you prefer putting then on the same line as if, you must add a semicolon to separate the test from the then: if [ -f fred.c ]; then ... fi

    The condition types that you can use with the test command fall into three types: string comparison, arithmetic comparison, and file conditionals.

     

    String Comparison Result string1 = string2 True if the strings are equal string1 != string2 True if the strings are not equal -n string True if the string is not null -z string True if the string is null (an empty string) Arithmetic Comparison Result expression1 -eq expression2 True if the expressions are equal expression1 -ne expression2 True if the expressions are not equal expression1 -gt expression2 True if expression1 is greater than expression2 expression1 -ge expression2 True if expression1 is greater than or equal to expression2 expression1 -lt expression2 True if expression1 is less than expression2 expression1 -le expression2 True if expression1 is less than or equal to expression2 ! expression True if the expression is false, and vice versa File Conditional Result -d file True if the file is a directory -e file True if the file exists. Note that historically the -e option        has not been portable, so -f is usually used. -f file True if the file is a regular file -g file True if set-group-id is set on file -r file True if the file is readable -s file True if the file has nonzero size -u file True if set-user-id is set on file -w file True if the file is writable -x file True if the file is executable

     

    Condition structures

    if condition then statements else statements fi

     

    elif

    If you want the echo command to delete the trailing new line, the most portable option is to use the printf command (see the printf section later in this chapter), rather than the echo command. Some shells use echo –e, but that’s not supported on all systems. bash allows echo -n to suppress the new line, so if you are confident your script needs to work only on bash, we suggest using that syntax.

     

    for variable in values do statements done

     

    What would happen if you changed the first line from for foo in bar fud 43 to for foo in “bar fud 43”? Remember that adding the quotes tells the shell to consider everything between them as a single string. This is one way of getting spaces to be stored in a variable.

     

    While

     

    while condition do statements done

     

    #!/bin/sh echo “Enter password” read trythis while [ “$trythis” != “secret” ]; do echo “Sorry, try again” read trythis done exit 0

     

    until

     

    until condition do statements done

     

    In general, if a loop should always execute at least once, use a while loop; if it may not need to execute at all, use an until loop.

     

    case

     

    case variable in pattern [ | pattern] ...) statements;; pattern [ | pattern] ...) statements;; ... esac

     

    Notice that each pattern line is terminated with double semicolons (;;). You can put multiple state- ments between each pattern and the next, so a double semicolon is needed to mark where one statement ends and the next pattern begins.

     

    #!/bin/sh echo “Is it morning? Please answer yes or no” read timeofday case “$timeofday” in yes) echo “Good Morning”;; no ) echo “Good Afternoon”;; y ) echo “Good Morning”;; n ) echo “Good Afternoon”;; * ) echo “Sorry, answer not recognized”;; esac exit 0

    It doesn’t look for a best match, just the first match. The default condition often turns out to be the impossible condition, so using * can help in debugging scripts.

     

    #!/bin/sh echo “Is it morning? Please answer yes or no” read timeofday case “$timeofday” in yes | y | Yes | YES ) echo “Good Morning”;; n* | N* ) echo “Good Afternoon”;; * ) echo “Sorry, answer not recognized”;; esac exit 0

     

    remember using " | " as or operation

     

    #!/bin/sh echo “Is it morning? Please answer yes or no” read timeofday case “$timeofday” in yes | y | Yes | YES ) echo “Good Morning” echo “Up bright and early this morning” ;; [nN]*) echo “Good Afternoon” ;; *) echo “Sorry, answer not recognized” echo “Please answer yes or no” exit 1 ;; esac exit 0

     

    You must be careful to put the most explicit matches first and the most general match last. This is important because case executes the first match it finds, not the best match. If you put the *) first, it would always be matched, regardless of what was input.

    Lists

     

    The AND List

     

    The AND list construct enables you to execute a series of commands, executing the next command only if all the previous commands have succeeded. The syntax is

     

    statement1 && statement2 && statement3 && ...

     

    #!/bin/sh touch file_one rm -f file_two if [ -f file_one ] && echo “hello” && [ -f file_two ] && echo “ there” then echo “in if” else echo “in else” fi exit 0

     

    The OR list

     

    The OR list construct enables us to execute a series of commands until one succeeds, and then not execute any more. The syntax is as follows:

     

    statement1 || statement2 || statement3 || ...

     

    #!/bin/sh rm -f file_one if [ -f file_one ] || echo “hello” || echo “ there” then echo “in if” else echo “in else” fi exit 0

     

    Functions

     

    To define a shell function, simply write its name followed by empty parentheses and enclose the statements in braces:

     

    function_name () {      statements }

     

    #!/bin/sh foo() { echo “Function foo is executing” } echo “script starting” foo echo “script ended” exit 0

     

    There is no foward declaration in shell, so defind the function before you use it

     

    Local variable and global variable

     

    #!/bin/sh sample_text=”global variable” foo() { local sample_text=”local variable” echo “Function foo is executing” echo $sample_text } echo “script starting” echo $sample_text foo echo “script ended” echo $sample_text exit 0

    Return a value

    #!/bin/sh

     

    yes_or_no() { echo “Is your name $* ?” while true do echo -n “Enter yes or no: “ read x case “$x” in y | yes ) return 0;; n | no ) return 1;; * ) echo “Answer yes or no” esac done }

     

    echo “Original parameters are $*“ if yes_or_no “$1” then echo “Hi $1, nice name” else echo “Never mind” fi exit 0

     

    Commonds

     

    break

     

    We use break to escape from for while and until

     

    #!/bin/sh rm -rf fred* echo > fred1 echo > fred2 mkdir fred3 echo > fred4 for file in fred* do if [ -d “$file” ]; then break;

    fi done echo first directory starting fred was $file rm -rf fred* exit 0

     

    :

     

    The colon command is a null command. It’s occasionally useful to simplify the logic of conditions, being an alias for true. Since it’s built-in, : runs faster than true, though its output is also much less readable.

     

    #!/bin/sh rm -f fred if [ -f fred ]; then : else echo file fred did not exist fi exit

     

    continue

     

    Just like the continue in C

     

    #!/bin/sh rm -rf fred* echo > fred1 echo > fred2 mkdir fred3 echo > fred4

     

    for file in fred* do if [ -d “$file” ]; then echo “skipping directory $file” continue fi echo file is $file done rm -rf fred* exit 0

     

    for x in 1 2 3 do echo before $x continue 1 echo after $x done

     

    The (dot) commond

    .

     

    excute the commond in the current sheel

    . ./shell_script

     

    echo

     

    eval

     

    foo=10 x=foo y=’$’$x echo $y

     

    gives $foo

    but

     

    foo=10 x=foo eval y=’$’$x echo $y

     

    gives 10

     

    exec

     

    exit n

     

    The exit command causes the script to exit with exit code n

     

    export

     

    #!/bin/sh echo “$foo” echo “$bar”

     

    #!/bin/sh foo=”The first meta-syntactic variable” export bar=”The second meta-syntactic variable” export2

     

    The commands set -a or set -allexport will export all variables thereafter.

     

    expr

    x=$(expr $x + 1)

     

    Expression Evaluation Description expr1 | expr2 expr1 if expr1 is nonzero, otherwise expr2 expr1 & expr2 Zero if either expression is zero, otherwise expr1 expr1 = expr2 Equal expr1 > expr2 Greater than expr1 >= expr2 Greater than or equal to expr1 < expr2 Less than expr1 <= expr2 Less than or equal to expr1 != expr2 Not equal expr1 + expr2 Addition expr1 - expr2 Subtraction expr1 * expr2 Multiplication expr1 / expr2 Integer division expr1 % expr2 Integer modulo

     

    printf

    just like the one in C/C++

     

    printf “format string“ parameter1 parameter2 ...

     

    Escape Sequence Description /“ Double quote // Backslash character /a Alert (ring the bell or beep) /b Backspace character /c Suppress further output /f Form feed character /n Newline character /r Carriage return /t Tab character /v Vertical tab character /ooo The single character with octal value ooo /xHH The single character with the hexadecimal value HH

     

    return

     

    set

     

    #!/bin/sh echo the date is $(date) set $(date) echo The month is $2 exit 0

     

    shift

     

    #!/bin/sh while [ “$1” != “” ]; do echo “$1” shift done exit 0

     

    trap

     


    最新回复(0)