shell syntax

来源:互联网 发布:幽默app软件下载 编辑:程序博客网 时间:2024/06/10 12:12

1.Variables

xxx@xxx-pc ~ $ salutation=helloxxx@xxx-pc ~ $ echo $salutation helloxxx@xxx-pc ~ $ read salutationwhat?   //user inxxx@xxx-pc ~ $ echo $salutation what?

Try It Out:

#!/bin/shmyvar="Hi there"echo $myvarecho "$myvar"echo '$myvar'echo \$myvarecho Enter some textread myvarecho '$myvar' now equals $myvarexit 0-----------------------//output:Hi thereHi there$myvar$myvarEnter some textHello World     //user-in$myvar now equals Hello World

Environment Variables

$HOME  //the home directory of the current user$PATH  //a colon-separated list of directories to search for commands$PS1//a cmd prompt, frequently $.    [\u@\h \w] $ $PS2   //a secondary prompt, used when prompting for additional input; usually >.$IFS   //an input field separator.separate word ,usually space$0     //shell script$#     //the number of parameters passed to script$$//process ID of shell script, use for example /tmp/tmpfile_$$man env

Parameter Variables

$1,$2...   //parameters$* //a list of parameters.$@--ex.--------xx@xxx-pc ~ $ IFS=''  /* '\0' */xxx@xxx-pc ~ $ echo "$@"foo bar bamxxx@xxx-pc ~ $ echo "$*"foobarbamxxx@xxx-pc ~ $ unset IFSxxx@xxx-pc ~ $ echo "$*"foo bar bam

Try It Out

#!/bin/shsalutation="Hello"echo $salutationecho "The program $0 is now running"echo "The second parameter was $2"echo "The first parameter was $1"echo "The parameter list was $*"echo "The user's home directory is $HOME"echo "Please enter a new greeting"read salutationecho $salutationecho "The script is now complete"exit 0------------------------------xxx@xxx-pc ~ $ sh 1.sh foo bar bazHelloThe program 1.sh is now runningThe second parameter was barThe first parameter was fooThe parameter list was foo bar bazThe user's home directory is /home/xxxPlease enter a new greetingsire    //user-insireThe script is now complete

Conditions

The test or [ Command

xxx@xxx-pc ~ $ which test/usr/bin/test

check a file exists.

xxx@xxx-pc ~ $ if test -f 1.sh> then echo test> fitest/* or */xxx@xxx-pc ~ $ if [ -f 1.sh ]; then echo test; fitest

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

/* String Comparison  &  Result */string1 = string2   //True if the strings are equalstring1 != 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 equalexpression1 -ne expression2   // not equalexpression1 -gt expression2   // greater than expression1 -ge expression2   // greater than or equal expression1 -lt expression2   // less than expression1 -le expression2   // less than or equal ! 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
#!/bin/shif [ -f /bin/bash ]then  echo "file /bin/bash exists"fiif [ -d /bin/bash ]then  echo "/bin/bash is a directory"else  echo "/bin/bash is NOT a directory"fi-------------------xxx@xxx-pc ~ $ sh 1.sh file /bin/bash exists/bin/bash is NOT a directory

Control Structures

if

#!/bin/shecho "It is morning? Please answer yes or no"read timeofdayif [ $timeofday = "yes" ]; then  echo "Good morning"else  echo "Good afternoon"fiexit 0----------------------xxx@xxx-pc ~ $ sh 1.sh It is morning? Please answer yes or noyes     //user-inGood morning

elif

Try It Out :

#!/bin/shecho "It is morning? Please answer yes or no"read timeofdayif [ $timeofday = "yes" ]; then  echo "Good morning"elif [ $tmeofday = "no" ]; then  echo "Good afternoon"else  echo "Sorry, $timeofday not recognized. Enter yes or no"  exit 1fiexit 0--------------------------xxx@xxx-pc ~ $ sh 1.sh It is morning? Please answer yes or no                    //push Enter, is null1.sh: 6: [: =: unexpected operator1.sh: 8: [: =: unexpected operatorSorry,  not recognized. Enter yes or no/* so we should alter like:if [ "$timeofday" = "yes" ]; then*/

bash allows echo -n to suppress(去除) the new line.

for

#!/bin/shfor foo in bar fud 43do   echo $foodoneexit 0-------------------------xxx@xxx-pc ~ $ sh 1.sh barfud43
/* find f*.sh */#!/bin/shfor file in $(ls f*.sh); do  echo $filedoneexit 0

while

a rather poor password-checking program:

#!/bin/shecho "Enter password"read trythiswhile [ "$trythis" != "secret" ]; do  echo "Sorry, try again"  read trythisdoneexit 0---------------------------Enter passwordsss     //user-inSorry, try againsecret  //user-in

until

until conditiondo  statementsdone

an until loop, you can set up an alarm that is initiated when another user, whose login name you pass on the command line**, logs on**

#!/bin/shuntil who | grep "$1" > /dev/nulldo  sleep 60done#now ring the bell and announce the expected user.echo -e '\a'echo "**** $1 has just logged in ****"exit 0-------------------------xxx@xxx-pc ~ $ sh f1.sh xxx-e **** xxx has just logged in ****

case

case variable in  pattern [ | pattern] ...) statements;;  pattern [ | pattern] ...) statements;;  ...esac
  1. User Input
#!/bin/shecho "Is it morning? Please answer yes or no"read timeofdaycase "$timeofday" in  yes) echo "Good Morning";;  no ) echo "Good Afternoon";;  y  ) echo "Good Morning";;  n  ) echo "Good Afternoon";;  *  ) echo "Sorry, answer not recognized";;esacexit 0

2 . Putting Patterns Together

#!/bin/shecho "Is it morning? Please answer yes or no"read timeofdaycase "$timeofday" in  yes | y | Yes | YES ) echo "Good Morning";;  n* | N* ) echo "Good Afternoon";;  *  ) echo "Sorry, answer not recognized";;esacexit 0

3.Executing Multiple Statements

#!/bin/shecho "Is it morning? Please answer yes or no"read timeofdaycase "$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/* more powerful : [yY] | [Yy][Ee][Ss] ) */

Lists

The AND List

#!/bin/shtouch file_onerm -f file_twoif [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there"then  echo "in if"else  echo "in else"fiexit 0-----------------------------------helloin else

The OR List

execute a series of commands until one succeeds, and then not execute any more.

#!/bin/shrm -f file_oneif [ -f file_one ] || echo "hello" || echo " there"then  echo "in if"else  echo "in else"fiexit 0------------------------helloin if
[ -f file_one ] && command for true || command for false

Statement Blocks

{} to make a statement block.

get_confirm && {    grep -v "$cdcatnum" $tracks_file > $temp_file    cat $temp_file > $tracks_file    echo     add_record_tracks}

Functions

function_name () {  statements}
#!/bin/shfoo() {    echo "Function foo is executing"}echo "script starting"fooecho "script ended"exit 0--------------------script startingFunction foo is executingscript ended
#!/bin/shsample_text="global variable"foo() {    local sample_text="local_variable"    echo "Function foo is executing"    echo $sample_text}echo "script starting"echo $sample_textfooecho "script ended"echo $sample_textexit 0--------------------------script startingglobal variableFunction foo is executinglocal_variablescript endedglobal variable

Try It Out

#!/bin/shyes_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"fiexit 0---------------------Original parameters are xxxIs your name xxx ?Enter yes or no: yHi xxx, nice name

Commands

break

#!/bin/shrm -rf fred*echo > fred1echo > fred2mkdir fred3echo > fred4for file in fred*do    if [ -d "$file" ]; then    break;    fidoneecho first directory starting fred was $filerm -rf fred*exit 0------------------first directory starting fred was fred3

The : Command

The colon command is a null command.

#!/bin/shrm -f fredif [ -f fred ]; then    :else    echo file fred did not existfiexit 0

continue

#!/bin/shrm -rf fred*echo > fred1echo > fred2mkdir fred3echo > fred4for file in fred*do    if [ -d "$file" ]; then    echo "skipping directory $file"    continue;    fi    echo file is $filedonerm -rf fred*exit 0##########file is fred1file is fred2skipping directory fred3file is fred4

continue can take the enclosing loop number at which to resume as an optional parameter so that you can partially jump out of nested loops. This parameter is rarely used, as it often makes scripts much harder to understand. For example

#!/bin/shfor x in 1 2 3do    echo before $x    continue 1    echo after $xdoneexit 0####before 1before 2before 3

The . Command

usually create a subshell for a script.
The dot ( . ) command executes the command in the current shell:

. ./shell_script

set the environment

#!/bin/shversion=classicPATH=/usr/local/old_bin:/usr/bin:/bin:.PS1="classic> "-------------#!/bin/shversion=latestPATH=/usr/local/new_bin:/usr/bin:/bin:.PS1="latest version>"#################$ . ./classic_setclassic> echo $versionclassicclassic> . ./latest_setlatest version> echo $versionlatestlatest version>

The scripts are executed using the dot command, so each script is executed in the current shell. This enables the script to change environment settings in the current shell, which remains changed even when the script finishes executing.

echo

suppressing a newline

echo -nstring to output”  // linuxecho -estring to output\c”// \c for suppressing a newline

eval

The eval command enables you to evaluate arguments. It’s built into the shell and doesn’t normally exist as a separate command.

xxx@xxx-pc ~ $ foo=10xxx@xxx-pc ~ $ x=fooxxx@xxx-pc ~ $ y='$'$xxxx@xxx-pc ~ $ echo $y$fooxxx@xxx-pc ~ $ foo=10xxx@xxx-pc ~ $ x=fooxxx@xxx-pc ~ $ eval y='$'$xxxx@xxx-pc ~ $ echo $y10

printf

printf “format string“ parameter1 parameter2 ...
$ printf%s\n” hellohello$ printf%s %d\t%s” “Hi There” 15 peopleHi There 15    people

return

return takes a single numeric parameter that is available to the script calling the function. If no parameter is specified, then return defaults to the exit code of the last command.

set

The set command sets the parameter variables for the shell.

#!/bin/shecho the date is $(date)set $(date)echo The month is $2exit 0#############the date is Sat Sep 5 14:33:06 CST 2015The month is Sep

This program sets the parameter list to the date command’s output and then uses the positional parameter $2 to get at the month.
set -xwhich makes a script display a trace of its currently executing command.

shift

The shift command moves all the parameter variables down by one.

you can scan through all the positional parameters like this:

#!/bin/shwhile [ "$1" != "" ]; do    echo "$1"    shiftdoneexit 0

trap

The trap command is used to specify the actions to take on receipt(接收) of signals.
trap -l . detail : man 7 signal

trap command signal

To reset a trap condition to the default, simply specify the command as - .To ignore a signal, set the command to the empty string “” . A trap command with no parameters prints out the current list of traps and actions.

Signal   &  DescriptionHUP(1)  Hang up(挂起); usually sent when a terminal goes offline, or a user logs outINT(2)  Interrupt(中断); usually sent by pressing Ctrl+CQUIT(3)  Quit; usually sent by pressing Ctrl+\ABRT(6)  Abort(中止); usually sent on some serious execution errorALRM(14)  Alarm; usually used for handling timeoutsTERM(15)  Terminate(终止); usually sent by the system when it’s shutting down
#!/bin/shtrap 'rm -f /tmp/my_tmp_file_$$' INTecho creating file /tmp/my_tmp_file_$$date > /tmp/my_tmp_file_$$echo "press interrupt (CTRL_C) to interrupt ...."while [ -f /tmp/my_tmp_file_$$ ]; do    echo File exists    sleep 1doneecho The file no longer existstrap INT      // null to do echo creating file /tmp/my_tmp_file_$$date > /tmp/my_tmp_file_$$echo "press interrupt (control-c) to interrupt ...."while [ -f /tmp/my_tmp_file_$$ ]; do    echo File exists    sleep 1doneecho we never get hereexit 0################creating file /tmp/my_tmp_file_628press interrupt (CTRL_C) to interrupt ....File existsFile existsFile exists^CThe file no longer existscreating file /tmp/my_tmp_file_628press interrupt (control-c) to interrupt ....File existsFile existsFile existsFile existsFile exists^C

unset

The unset command removes variables or functions from the environment. It can’t do this to read-only variables defined by the shell itself, such as IFS. It’s not often used.

#!/bin/shfoo="Hello World"echo $foounset fooecho $foo############Hello World

Two More Useful Commands and Regular Expressions

The find Command

find / -name test -printfind / -mount -name test -print /* find quickly, don't search other filesystem directories*/
The full syntax for the find command is as follows:find [path] [options] [tests] [actions]

There are several options; the main ones are shown in the following table:

Option   &  Meaning-depth   Search the contents of a directory before looking at the directory itself.-follow   Follow symbolic links.-maxdepths N   Search at most N levels of the directory when searching.-mount (or -xdev )   Don’t search directories on other file systems.

Now for the tests. A large number of tests can be given to find , and each test returns either true or false .

Test Meaning-atime N   The file was last accessed N days ago.-mtime N   The file was last modified N days ago.-name pattern   The name of the file-newer otherfile   The file is newer than otherfile .-type C    type C, the most common are “d” for a directory and “f” for a regular file.-user username   The file is owned by the user with the given name.

You can also combine tests using operators. Most have two forms: a short form and a longer form, as shown in the following table:

Operator,   Short Form Operator,   Long Form Meaning!   -not   Invert the test.-a   -and    Both tests must be true.-o    -or    Either test must be true.

write the test “newer than file X or called a name that starts with an underscore,” you could write the following test:

\( -newer X -o -name "_*" \)

example:

$ find . -newer while2 -print../elif3./words.txt./words2.txt./_trap###################$ find . -newer while2 -type f -print./elif3./words.txt./words2.txt./_trap
find . \( -newer f1.sh -o -name "_*" \) -type f -print

//你必须转义圆括号保证不会被shell处理, 把*号用引号括起保证直接传递给find.

this is just a list of the most common actions:

Action   &  Meaning-exec command   Execute a command. This action must be terminated with a \; character pair.-ok command   Like -exec, prompts before executing. terminated with a \; character pair.-print   Print out the name of the file.-ls   Use the command ls -dils on the current file.

//-exec 和 -ok之后直到\; 都是其参数; 它们是嵌入式命令, 以\;结束.

The magic string “{}” is a special type of parameter to an -exec or -ok command and is replaced with the full path to the current file.

xxx@xxx-pc ~ $ find . -newer f1.sh -type f -exec ls -l {} \;

The grep Command

general regular expression parser.(通用正则表达式解析器) You use find to search your system for files, but you use grep to search files for strings. Indeed, it’s quite common to have grep as a command passed after -exec when using find .

grep [options] PATTERN [FILES]

If no filenames are given, it searches standard input.

Option   &  Meaning-c    print a count of the number of lines that match.-E    Turn on extended expressions.-h    Suppress the normal prefixing of each output line with the name of the file it was found in.-i    Ignore case.-l    List the names of the files with matching lines; don’t output the actual matched line.-v    Invert the matching pattern to select nonmatching lines, rather than matching lines.
$ grep in words.txt   //search "in"When shall we three meet again. In thunder, lightning, or in rain?I come, Graymalkin!$ grep -c in words.txt words2.txt   words.txt:2words2.txt:14$ grep -c -v in words.txt words2.txtwords.txt:9words2.txt:16

Regular Expressions

certain characters are processed in a special way.

Character   &  Meaning^    Anchor(指向) to the beginning of a line$    Anchor to the end of a line.    Any single character[ ]    The square braces contain a range of characters, any one of which may be matched, such as a range of characters like a–e or an inverted range by preceding the range with a ^ symbol.
Match Pattern   &  Meaning[:alnum:] Alphanumeric(字母和数字) characters[:alpha:] Letters[:ascii:] ASCII characters[:blank:] Space or tab[:cntrl:] ASCII control characters[:digit:] Digits[:graph:] Noncontrol, nonspace characters[:lower:] Lowercase letters[:print:] Printable characters[:punct:] Punctuation(标点符号) characters[:space:] Whitespace characters, including vertical tab[:upper:] Uppercase letters[:xdigit:] Hexadecimal(十六进制) digits

if the -E for extended matching is also specified, other characters that control the completion of matching may follow the regular expression . With grep it is also necessary to precede these characters with a \ .

Option   &  Meaning?   Match is optional but may be matched at most once*   Must be matched zero or more times+   Must be matched one or more times{n}   Must be matched n times{n,}   Must be matched n or more times{n,m}   Must be matched between n or m times, inclusive
xxx@xxx-pc ~ $ grep h$ *.sh    //line end in hf1.sh:#!/bin/shf2.sh:#!/bin/shxxx@xxx-pc ~ $ grep h[[:blank:]] *.sh    //word end in hf2.sh:echo The month is $2xxx@xxx-pc ~ $ grep Th.[[:space:]] *.sh    //three-letter start with Thf2.sh:echo The month is $2xxx@xxx-pc ~ $ grep -E [a-z]\{5\} *.sh    //five-letter wordf1.sh:unset foof2.sh:echo The month is $2

Command Execution

#!/bin/shecho The current directory is $PWDecho The current users are $(who)exit 0################The current directory is /home/xxxThe current users are xxx tty8 2015-09-05 09:35 (:0) xxx pts/2 2015-09-05 13:47 (:0)

Since the current directory is a shell environment variable, the first line doesn’t need to use this command execution construct.

xxx@xxx-pc ~ $ whoisthere=$(who)xxx@xxx-pc ~ $ echo $whoistherexxx tty8 2015-09-05 09:35 (:0) xxx pts/2 2015-09-05 13:47 (:0)

If you ever find yourself trying to convert a set of parameters that are the output of a command on standard output and capture(捕获) them as arguments for a program, you may well find the command xargs can do it for you.

Arithmetic Expansion

#!/bin/shx=0while [ "$x" -ne 10 ]; do    echo $x    x=$(($x+1))doneexit 0

Parameter Expansion

Parameter Expansion   &  Description${param:-default}   If param is null, then set it to the value of default .${#param}   Gives the length of param${param%word}   From the end, removes the smallest part of param that matches word and returns the rest${param%%word}   From the end, removes the longest part of param that matches word and returns the rest${param#word}   From the beginning, removes the smallest part of param that matches word and returns the rest${param##word}   From the beginning, removes the longest part of param that matches word and returns the rest
#!/bin/shunset fooecho ${foo:-bar}foo=fudecho ${foo:-bar}foo=/usr/bin/X11/startxecho ${foo#*/}echo ${foo##*/}bar=/usr/local/etc/local/networksecho ${bar%local*}echo ${bar%%local*}exit 0##############barfudusr/bin/X11/startxstartx/usr/local/etc//usr/

convert a GIF file into a JPEG file using the cjpeg program:

$ cjpeg image.gif > image.jpg
#!/bin/shfor image in *.gifdo    cjpeg $image > ${image%%gif}jpgdoneexit 0

Here Documents

One special way of passing input to a command from a shell script is to use a here document.

#!/bin/shcat <<!FUNKY!hellothis is a heredocument!FUNKY###############hellothis is a heredocument
#!/bin/shed a_text_file <<!FunkyStuff!    // ed editor3                 //move to 3rd lined                 //delete.,\$s/is/was/     //current line, replacew               //writeq               //quit!FunkyStuff!exit 0##############xxx@xxx-pc ~ $ cat a_text_fileThat is line 1That is line 2That was line 4

Debugging Scripts

Command Line | Option set Option | Descriptionsh -n <script> | set -o noexec   | Checks for syntax errors only;               | set -n          | doesn’t execute commandssh -v <script> | set -o verbose  | Echoes(回显) commands before               | set -v          | running themsh -x <script> | set -o xtrace   | Echoes commands after pro-               | set -x          | cessing on the command linesh -u <script> | set -o nounset  | Gives an error message when               | set -u          | an undefined variable is used

For an initial check, you can use the command-line option, but for finer debugging, you can put the xtrace flags (setting an execu-
tion trace on and off) inside the script around the problem code. The execution trace causes the shell to print each line in the script, with variables expanded, before executing the line.

Use the following command to turn xtrace on:

set -o xtrace

Use this command to turn xtrace off again:

set +o xtrace

In the shell, you can also find out the program state wherever it exits by trapping the EXIT signal with a line something like the following placed at the start of the script:

trap ‘echo Exiting: critical variable = $critical_variableEXIT
0 0
原创粉丝点击