shell-脚本入门【转】

简介:

转自:http://blog.csdn.net/gexiaobaohelloworld/article/details/7973846

目录(?)[-]

  1. Shell环境设置
    1. 1 登陆欢迎信息
    2. 2 bash环境配置文件
    3. 3 常见的环境变量
      1. 31 环境变量
      2. 32 设置方法
    4. 4 bash中的通配符和特殊符号和组合按键
      1. 41 通配符
      2. 42 特殊字符
      3. 43 组合按键
    5. 4 数据流重定向
    6. 5 命令执行的判断依据
    7. 5 shell脚本调试
  2. 语法基本介绍
    1. 1 开头
    2. 2 注释 
    3. 3 变量 
      1. 34 参数扩展正则表达式
    4. 4 declare
    5. 5 数值计算
      1. 方法1declare -i
      2. 方法2var expression
    6. 6 数组
    7. 7 语句块
    8. 7 特殊变量
    9. 8 输入与输出
    10. 9 Here Document说明文字
    11. 10 退出状态
    12. 11 测试结构与操作符
  3. shell命令与流程控制
    1. 1 Unix 命令 
    2. 3 流程控制 
      1. 31if语句 
      2. 32case
      3. 33 selsect
      4. 34while
      5. 35 until
      6. 36for
      7. 37 beak
      8. 38 continue
    3. 4 source命令和dot命令
    4. 5 export命令
    5. 6 exec命令
    6. 7 shift命令
    7. 8 trap命令
    8. 9 多进程控制
  4. 函数
    1. 1 函数定义语法 
    2. 2 函数返回值的两种办法
    3. 3 实例分析
  5. 我的脚本模板
  6. 实例

http://www.blogjava.net/liubowu/archive/2007/06/25/99317.html

1 Shell环境设置

1.1 登陆欢迎信息

终端机接口 (tty1 ~ tty6) 登陆的时候,会有几行提示的字符串,在 在CODE上查看代码片派生到我的代码片
  1. #source ~/.bashrc  
  2. #.  ~/.bashrc  


info bash builtin命令可以列出所有的bash内置命令。

File: bash.info,  Node: Builtin Index,  Next: Reserved Word Index,  Prev: Copying This Manual,  Up: Top

Index of Shell Builtin Commands
*******************************


* Menu:

* .:                                     Bourne Shell Builtins.
                                                              (line  16)
* ::                                     Bourne Shell Builtins.
                                                              (line  11)
* [:                                     Bourne Shell Builtins.
                                                              (line 212)
* alias:                                 Bash Builtins.       (line  11)
* bg:                                    Job Control Builtins.
                                                              (line   7)
* bind:                                  Bash Builtins.       (line  21)
* break:                                 Bourne Shell Builtins.
                                                              (line  29)
* builtin:                               Bash Builtins.       (line  92)
* caller:                                Bash Builtins.       (line 100)
* cd:                                    Bourne Shell Builtins.
                                                              (line  36)
* command:                               Bash Builtins.       (line 117)
* compgen:                               Programmable Completion Builtins.
                                                              (line  10)
* complete:                              Programmable Completion Builtins.
                                                              (line  28)
* continue:                              Bourne Shell Builtins.
                                                              (line  55)
* declare:                               Bash Builtins.       (line 136)
* dirs:                                  Directory Stack Builtins.
                                                              (line   7)
* disown:                                Job Control Builtins.
                                                              (line  83)
* echo:                                  Bash Builtins.       (line 191)
* enable:                                Bash Builtins.       (line 243)
* eval:                                  Bourne Shell Builtins.
                                                              (line  63)
* exec:                                  Bourne Shell Builtins.
                                                              (line  70)
* exit:                                  Bourne Shell Builtins.
                                                              (line  82)
* export:                                Bourne Shell Builtins.
                                                              (line  88)
* fc:                                    Bash History Builtins.
                                                              (line  10)
* fg:                                    Job Control Builtins.
                                                              (line  16)
* getopts:                               Bourne Shell Builtins.
                                                              (line 103)
* hash:                                  Bourne Shell Builtins.
                                                              (line 145)
* help:                                  Bash Builtins.       (line 271)
* history:                               Bash History Builtins.
                                                              (line  39)
* jobs:                                  Job Control Builtins.
 * kill:                                  Job Control Builtins.
                                                              (line  57)
* let:                                   Bash Builtins.       (line 280)
* local:                                 Bash Builtins.       (line 287)
* logout:                                Bash Builtins.       (line 297)
* popd:                                  Directory Stack Builtins.
                                                              (line  37)
* printf:                                Bash Builtins.       (line 301)
* pushd:                                 Directory Stack Builtins.
                                                              (line  58)
* pwd:                                   Bourne Shell Builtins.
                                                              (line 163)
* read:                                  Bash Builtins.       (line 326)
* readonly:                              Bourne Shell Builtins.
                                                              (line 172)
* return:                                Bourne Shell Builtins.
                                                              (line 187)
* set:                                   The Set Builtin.     (line   9)
* shift:                                 Bourne Shell Builtins.
                                                              (line 200)
  * shopt:                                 Bash Builtins.       (line 387)
* source:                                Bash Builtins.       (line 618)
* suspend:                               Job Control Builtins.
                                                              (line  94)
* test:                                  Bourne Shell Builtins.
                                                              (line 212)
* times:                                 Bourne Shell Builtins.
                                                              (line 278)
* trap:                                  Bourne Shell Builtins.
                                                              (line 283)
* type:                                  Bash Builtins.       (line 622)
* typeset:                               Bash Builtins.       (line 653)
* ulimit:                                Bash Builtins.       (line 659)
* umask:                                 Bourne Shell Builtins.
                                                              (line 324)
* unalias:                               Bash Builtins.       (line 737)
* unset:                                 Bourne Shell Builtins.
                                                              (line 341)
* wait:                                  Job Control Builtins.
                                                              (line  73)
                                                           (line  25)

可以通过使用命令info builtin查看所有命令的详细用法
转载:http://blog.chinaunix.net/u2/71769/showart_2226369.html

1.3 常见的环境变量

1.3.1 环境变量

存储在文件/etc/profile中

P A T H s h e l l HOME:当前用户主目录。
M A I L SHELL:是指当前用户用的是哪种Shell。
H I S T S I Z E LOGNAME:是指当前用户的登录名。
H O S T N A M E LANG/LANGUGE:是和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
PS1:是基本提示符,对于root用户是#,对于普通用户是 ,也可以使用一些更复杂的值。
P S 2 > IFS:输入域分隔符。当shell读取输入时,用来分隔单词的一组字符,它们通常是空格、制表符和换行符。
0 s h e l l #:传递给脚本的参数个数。
$$:shell脚本的进程号,脚本程序通常会用它生成一个唯一的临时文件,如/tmp/tmfile_$


1.3.2 设置方法

echo:显示指定环境变量。
export:设置新的环境变量。
env:显示所有环境变量。
set:显示所有本地定义的shell变量。
unset:清除环境变量。

将一个路径加入到PATH变量中:

如在PATH 这个变量当中“累加”一个新目录 这个目录

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. #1,控制台中:  
  2. P A T H =" PATH":/my_new_path"  
  3. #2,修改profile文件:  
  4. $ vi /etc/profile  
  5. 在里面加入:  
  6. export PATH="$PATH:/my_new_path"  
  7. #3,修改.bashrc文件:  
  8. $ vi /root/.bashrc  
  9. 在里面加入:  
  10. export PATH="$PATH:/my_new_path"  
  11. #后两种方法一般需要重新注销系统才能生效,最后可以通过echo命令测试一  

1.4 bash中的通配符和特殊符号和组合按键

注意,这里的通配符虽然和正则表达式相似,但是是基于bash解释器解析的,而正则表达式由正则引擎的软件(如awk,grep,sed等)解析,二者完全不同。

在CODE上查看代码片派生到我的代码片

  1. [root@linux ~]# ls test*     #那个 * 代表后面不论接几个字符都予以接受  
  2. [root@linux ~]# ls test?     #那个 ? 代表后面"一定"要接"一个"字符  
  3. [root@linux ~]# ls test???   #那个 ??? 代表"一定要接三个"字符!  
  4. [root@linux ~]# cp test[1-5] /tmp  # 将 test1, test2, test3, test4, test5 若存在的话,就拷贝到 /tmp  
  5. [root@linux ~]# cp test[!1-5] /tmp # 只要不是 test1, test2, test3, test4, test5 之外的其它 test?拷贝到 /tmp  
  6. [root@linux ~]# cd /lib/modules/`uname -r`/kernel/drivers  # 系统先执行 uname -r 找出输出结果;将结果累加在目录上面,来执行 cd 的功能!  
  7.                      = cd /lib/modules/$(uname -r)/kernel  #另外,这个 quot (`) 的功能,也可以利用 $() 来取代喔!  
  8. [root@linux ~]# cp *[A-Z]* /tmp   #表示文件中包含大写字母  
  9. [root@linux ~]# ls -lda /etc/*[35]* #表示文件中包含数字3或者5.  


1.4.2 特殊字符

# 注释
\ 转义字符
| 管道(pipe)
; 连续命令
~ 用户主文件夹
$ 变量前导符
& 作业控制的后台运行
! 逻辑非
/ 目录分隔符
>,>> 数据流重定向,输出导向,分别是“替换“和”增加“
<,<< 数据流重定向,输入导向
' ‘ 单引号,不具有变量置换功能
” “ 双引号,具有变量置换功能
` ` ` `中内容可以先执行的命令,也可以用$( )来替换
( ) 在中间为子shell的起始与结束
{ } 在中间为命令块的组合

1.4.3 组合按键

Ctrl + C 终止目前的命令
Ctrl + D 输入结束(EOF),例如邮件结束的时候;
Ctrl + M 就是 Enter 啦!
Ctrl + S 暂停屏幕的输出
Ctrl + Q 恢复屏幕的输出
Ctrl + U 在提示字符下,将整列命令删除
Ctrl + Z 暂停目前的命令

1.4 数据流重定向

linux的文件描述符FD,通常为10个:FD0~FD9。可以理解为linux跟踪打开文件,分配的一个数字,linux启动后会默认打开三个文件描述符:
0 标准输入 standard input
1 标准输出standard output
2 错误输出error output 

示例1:
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. ls -al >   newtxt  #本来ls -al 命令预设输出到屏幕,现在被重新导出到newtxt文档。  
  2. ls -al >>  newtxt  #现将ls -al 命令输出结果“增加”到文件newtxt末尾。  

示例2:想要将正确的与错误的数据分别存入不同的档案中:
• 1> :是将正确的数据输出到指定的地方去
• 2> :是将错误的数据输出到指定的地方去
[python]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. $ find /home -name testing > list_right 2> list_error  
有 Permission 的那几行错误信息都会跑到 list_error 这个档案中,至于正确的输出数据则会存到 list_right 这个档案中。

示例3:
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. 将错误信息不要(置于垃圾箱中/dev/null)  
  2. $ find /home -name testing > list_right 2> /dev/null   
  3. 将正确输出和错误输出都放置到同一个文件中testing中去  
  4. $ find /home -name testing > list 2> list <==错误写法  
  5. $ find /home -name testing > list 2>&1 <==正确写法  
另外,这里区分一下command>file  2>file 与  command>file 2>&1:
command > file 2>file 的意思是stdout和stderr都直接送到file中, file会被打开两次,这样stdout和stderr会互相覆盖,这样写相当使用了FD1和FD2两个同时去抢占file 的管道.
command >file 2>&1 这条命令就将stdout直接送向file, stderr 继承了FD1管道后,再被送往file,此时,file 只被打开了一次,也只使用了一个管道FD1,它包括了stdout和stderr的内容.

1.5 命令执行的判断依据

分号; cmd;cmd
多条命令顺序执行,执行顺序是从左到右的顺序。
与&& cmd1 && cmd2
若cmd1执行完毕且正确执行( ? = 0 c m d 2 c m d 2 ? !=0),则cmd2不执行
或|| cmd1 || cmd2
若cmd1执行完毕且正确执行( ? = 0 c m d 2 c m d 2 ? !=0),则开始执行cmd2
注意:这里的&&和||没有优先级关系,而是按照命令次序按序执行,所以对于:
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe  
该范例总会创建/tmp/abc/hehe文件。而不是先执行后面的。
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. [ -f file1 ] && exit 0 || exit 1  
该范例如果测试成功,则执行第一条命令,否则执行第二条命令。

1.5 shell脚本调试

Shell提供了一些用于调试脚本的选项,如下所示:
-n   读一遍脚本中的命令但不执行,用于检查脚本中的语法错误
-v   一边执行脚本,一边将执行过的脚本命令打印到标准错误输出
-x   提供跟踪执行信息,将执行的每一条命令和结果依次打印出来
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. $ sh -x ./script.sh  

2 语法基本介绍

2.1 开头

程序必须以下面的行开始(必须放在文件的第一行): 

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. #!/bin/sh   

符号#!用来告诉系统它后面的参数是用来执行该文件的程序,在这个例子中我们使用/bin/sh来执行程序。 

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. chmod +x filename  

当编辑好脚本时,如果要执行该脚本,还必须使其可执行。 这样才能用./filename 来运行。

2.2 注释 

在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。

文档可以这样写:

[python]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. ###################################################################################  
  2. ## The script is used for the regression of lineage jar with latest hive-exec..jar  
  3. ## , expression_analyze.jar, parse_common.jar, field_lineage.jar, ast_parser.jar  
  4. ## in trunk.  
  5. ###################################################################################  

区块可以这样写

[python]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. ###############################################  
  2. ## PARAMETERS  
  3. ##  

2.3 变量 

2.3.1 变量类型默认为字符串类型

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. #!/bin/sh   
  2. name="Jack"  
  3. s=" name, hello!" #注意等号"="前后都不能有空格。建议字符串用双引号(单引号表示纯字符串,不支持 等)。  
  4. echo  s           #输出Jack, hello!(若s用单引号,则输出 name, hello!)  
  5. unset s           #删除变量s  

2.3.2 单引号,双引号,无引号

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. s="./*"  
  2. echo $s     #这是变量,命令即为echo ./* ,通配符解开为:./1.sh ./a ./b ./c  
  3. echo ' s'   #这里的单引号表示一个字符串,字符串中的 等符号不能转义,输出:$s  
  4. echo " s"   #这里的双引号表示一个字符串,字符串中的 等符号要转义,其中$s为变量,所以输出./*  

2.3.3 参数扩展——花括号

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. num=2   
  2. echo "this is the $numnd" #this is the   

这并不会打印出"this is the 2nd",而仅仅打印"this is the ",因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以使用花括号来告诉shell我们要打印的是num变量: 

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. num=2   
  2. echo "this is the ${num}nd" #this is the 2nd  

这将打印: this is the 2nd 

2.3.4 参数扩展——正则表达式

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. ${name:-default} 使用一个默认值(一般是空值)来代替那些空的或者没有赋值的变量name;   
  2. ${name:=default}使用指定值来代替空的或者没有赋值的变量name;  
  3. ${name:?message}如果变量为空或者未赋值,那么就会显示出错误信息并中止脚本的执行同时返回退出码1。  
  4. ${#name} 给出name的长度  
  5. ${name%word} 从name的尾部开始删除与word匹配的最小部分,然后返回剩余部分  
  6. ${name%%word} 从name的尾部开始删除与word匹配的最长部分,然后返回剩余部分  
  7. ${name#word} 从name的头部开始删除与word匹配的最小部分,然后返回剩余部分  
  8. ${name##word} 从name的头部开始删除与word匹配的最长部分,然后返回剩余部分  

举例如下,使用cjpeg命令将一个GIF的文件转换为JPEG的文件:

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. $ cjpeg image.gif > image.jpg  
  2. 也许有时我们会在大量的文件上进行这样的操作.这时我们如何自动重定向?我们可以很容易的这样来做:  
  3. #!/bin/sh  
  4. for image in *.gif  
  5. do  
  6.    cjpeg  i m a g e > {image%%gif}jpg  
  7. done  


2.3.4 注意变量与变量字符串的问题:

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. read a  
  2. if [ $a = "yes" ];then  
  3. echo "OK"  
  4. fi  
  5. if [ "$a" = "yes" ];then  
  6. echo "OK"  
  7. fi  

这里 a a " a"是对变量a做字符串处理结果。如果read a 时直接回车,那么 a "" , i f [ =" y e s " ] 使 变量。

2.3.5 注意打印"*"的问题:

[python]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. #!/bin/sh  
  2. sql='select * from gexing;'  
  3. echo  $sql  #其中的*会被替换成所有文件,这就相当于echo select * from table;  
  4. echo "$sql" #这就相当于echo "select * from table"  
2.3.6 变量/字符串连接:
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. names= v a r n a m e 1 var_name2   #注意,两个变量之间没有空格  
  2. sentence=${names}"hello"     #直接连接  

2.4 declare

shell中的变量类型默认为字符串类型,但可以通过declare语法来指定变量的其他类型。
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. 语法:  
  2. declare [+/-][afrix]  variable  
  3. 说明:  
  4. +/- "-"可用来指定变量的属性,"+"则是取消变量所设的属性。  
  5. -a 定义变量variable为数组(array)类型  
  6. -i  定义变量variable为整数(integer)类型  
  7. -r  定义变量variable为只读(readonly)类型  
  8. -x  用法与export一样,将variable设置为环境变量  

2.5 数值计算

方法1,declare -i

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. 示例1:让变量 sum 保存 100+300+50 的加和结果  
  2. [root@linux ~]# sum=100+300+50  
  3. [root@linux ~]# echo $sum       #结果为:100+300+50     
  4. [root@linux ~]# declare -i sum=100+300+50  
  5. [root@linux ~]# echo $sum       #结果为:450          
  6.   
  7. 示例2:生成随机数  
  8. [root@linux ~]# declare -i number= R A N D O M 10 / 32767 ; e c h o number  

方法2,var=$ (( expression ))

[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. foo=1  
  2. foo= ( ( foo+1))  
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
  1. echo $ (( 13 % 3 ))  

2.6 数组

定义:shell支持一维数组,但并不限定数组大小,数组下标从0开始。
修改:对于数组修改操作,可以再对其重新赋值;
删除:如果要删除一个已经赋值后的元素则需要借助一个外部命令:unset,如:unset array[0]可清空下标为0的元素,此时数组大小减一;unset array[@]可以清空整个数组元素所有元素。
[plain]  view plain  copy 在CODE上查看代码片派生到我的代码片
    1. #!/bin/bash  
    2.   
    3. #赋值  
    4. a[0]=1              #第一种赋值方法  
    5. a[1]=2  
    6. a[2]=3  
    7. b=(6,7,8,9,10)      #第二种赋值方法  
    8.   
    9. #取值  
    10. echo   {b[0]}       #用 {数组名[下标]},下标是从0开始。下标是*或者@,则得到整个数组内容。输出6  
    11. echo   {b[*]:1:3}   #直接通过 {数组名[@或*]:起始位置:长度}切片原先数组,输出7 8 9  
    12. echo  ${b[*]::3}    #输出6 7 8(前三个元素) 













本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/6141577.html,如需转载请自行联系原作者
相关文章
|
20天前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
58 1
|
6天前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
22 2
6种方法打造出色的Shell脚本
|
11天前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
36 6
|
8天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
60 12
|
1月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
37 2
|
2月前
|
Shell
shell脚本变量 $name ${name}啥区别
shell脚本变量 $name ${name}啥区别
|
2月前
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
238 2
|
30天前
|
存储 Shell Linux
【Linux】shell基础,shell脚本
Shell脚本是Linux系统管理和自动化任务的重要工具,掌握其基础及进阶用法能显著提升工作效率。从简单的命令序列到复杂的逻辑控制和功能封装,Shell脚本展现了强大的灵活性和实用性。不断实践和探索,将使您更加熟练地运用Shell脚本解决各种实际问题
20 0
|
2月前
|
Shell
Shell脚本有哪些基本语法?
【9月更文挑战第4天】
60 18