shell脚本基础

shell脚本

· 可以运行的文本文件,可以实现某种功能。

· 提前设计可执行语句,用来完成特定任务的文件;

· 将命令都写入到文本文件(命令的堆积),然后赋予文本文件以可执行权限;

· 文件名以.sh结尾;

shell脚本的优势:

· 将重复的任务流程化;

· 将复杂的任务简单化;

· 将人工干预的任务自动化;

非交互式shell脚本:

· 需要提前设计、智能化难度大;

· 批量执行、效率高;

· 方便在后台静默运行;

规范的shell脚本的一般组成:

· #!环境声明(声明下边的可执行代码用什么程序翻译)

· 以#开头的是注释行,不会执行

· 可执行代码

· 实例:

]# vim /root/hello.sh

#!/bin/bash                            #环境声明,下边的命令用bash执行

# 以#开头的行是注释行,不会执行             #注释

# 下边的是可执行代码
echo "Hello World!"                    #可执行代码


#切换到末行模式
:wq                                    #保存并退出


]# chmod +x /root/hello.sh             #添加可执行权限
]# /root/hello.sh                      #以绝对路径执行脚本文件


管道:

· 使用 " | "符号 作为管道操作

· 将 | 前一条命令的标准输出交给后一条命令处理

[root@shell ~]# cat /etc/passwd | grep "root"    #将cat后的passwd文件交给后边的grep命令处理
root:x:0:0:root:/root:/bin/bash



重定向:

**    · 输出重定向**

- 将输出重定向到 屏幕 或设备 或文件

 >    :只收集前面命令的 正确输出,将其正确输出写入文本文件
2>    :只收集前面命令的 错误输出,将其错误输出写入文本文件
&>    :收集前面命令的 正确&错误输出,将正确&错误 输出写入文本文件
>&2   :收集前面命令的输出指定为错误输出,配合【exit 非0值】使用


[root@shell ~]# echo "hello world" > /1.txt


[root@shell ~]# cat /1.txt /etc/   >  /a.txt        #收集正确输出
cat: /etc/: Is a directory 
[root@shell ~]# cat /a.txt                          #文件中只有正确的输出信息
hello world


[root@shell ~]# cat /1.txt /etc/   2>    /a.txt     #收集错误输出
hello world
[root@shell ~]# cat /a.txt                          #文件中只有错误输出
cat: /etc/: Is a directory


[root@shell ~]# cat /1.txt /etc    &>   /a.txt      #收集正确和错误输出
[root@shell ~]# cat /a.txt                          #文件中有正确和错误的输出
hello world
cat: /etc: Is a directory


[root@test ~]# vim test.sh
echo "我错了"  >&2                                   #将输出指定为错误输出
exit 1                                              #将退出码设置为1,默认正确退出码为0
[root@test ~]# chmod +x test.sh 
[root@test ~]# ./test.sh 
[root@test ~]# echo $?
1                                                   #上调命令为错误输出



**    ·输入重定向**

[root@test ~]# cat > /a.txt <<EOF
> 此处写入cat的文本,重定向输入给/a.txt
> <<表示接受一个输入结束的标识,当在行首输入这个标识后,会结束输入
> EOF

[root@test ~]# cat /a.txt 
此处写入cat的文本,重定向输入给/a.txt
<<表示接受一个输入结束的标识,当在行首输入这个标识后,会结束输入


黑洞设备:

· /dev/null

· 专门收集无用的输出信息,使用后屏幕不再显示相关提示信息

[root@test ~]# ls /                                       #ls正常显示输出
bin   dev  home  lib64	mnt  proc  run	 srv  tmp  var
boot  etc  lib	 media	opt  root  sbin  sys  usr

[root@test ~]# ls / &> /dev/null                          #将ls的输出写入黑洞
                                                          #屏幕没有任何输出


变量:

**    · 什么是变量**

- 以不变的名称存放可能会变化的值;

- 方便以固定名称重复使用某个值;

- 提高对任务需求、运行环境变化的适应能力;

- 为了增加脚本适应多变的环境、多变的需求、使用方便性,所以需要使用变量;

**    · 变量的基本格式**

- 赋值: 变量名=变量值

- 引用: $变量名

- 查看: ]# echo $变量名;  echo ${变量名}        #使用 ${} 是为了断开变量名与其他字符混合,造成变量不存在

**    · 设置变量时的注意事项**

- 若指定的变量名已存在,相当于为此变量重新赋值。           ]# a=10; a=15; echo $a  ==>  15

- 等号两边不能有空格。

- 变量名只能由字母、数字、下划线组成,区分大小写。        ]# a_1=1; A=1

- 变量名不能以数字开头,不要使用关键字和特殊字符

环境变量

    · USER :储存当前登陆的用户

[root@shell2 ~]# echo $USER              #显示$USER的变量值
root
[root@shell2 ~]# useradd testuser        #创建一个测试用户
[root@shell2 ~]# su - testuser           #切换到测试用户
[testuser@shell2 ~]$ echo $USER          #显示当前的用户
testuser

位置变量

    · 在执行脚本时提供的默认命令行参数

    · 格式: ]# 脚本.sh $1 $2 $3 ...

[root@shell2 ~]# vim shell1.sh

#!/bin/bash
echo $1
echo $2
echo $3

[root@shell2 ~]# chmod +x shell1.sh 
[root@shell2 ~]# ./shell1.sh hh1 hh2 hh3
hh1
hh2
hh3

预定义变量

    $# :输出已加载的位置变量的个数(即运行脚本时,在脚本后面写的参数数量)

    $* :输出所有位置变量的值

    $? :输出程序退出后的状态值,0表示正常,非0表示异常

[root@shell2 ~]# vim shell2.sh 
#!/bin/bash
echo $1
echo $2
echo $3
echo $#                                        #显示参数总个数
echo $*                                        #显示所有参数值

[root@shell2 ~]# chmod +x shell2.sh 
[root@shell2 ~]# ./shell2.sh aa bb cc dd ee
aa
bb
cc
5                                              # $#的输出
aa bb cc dd ee                                 # $*的输出


[root@shell2 ~]# ping -c 2 127.0.0.1           # 发2个包,ping正常ip
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.025 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.025/0.041/0.058/0.017 ms
[root@shell2 ~]# echo $?
0

[root@shell2 ~]# ping -c 2 1.2.3.4            # 发2个包,瓶错误ip
PING 1.2.3.4 (1.2.3.4) 56(84) bytes of data.
--- 1.2.3.4 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms

基本符号

$[] :运算,计算器。                                                                 ]# echo $[1+2]    ==> 3

''   :单引号,让引号中间的特殊字符无效化,变为普通字符。        ]# echo '$a'    ==> $a

$() | `` :$()或者反撇号,将命令的输出结果作为参数。                   ]# mkdir $(data +%F)    ==> 2019-01-22

[root@shell2 ~]# echo $[1+1]
2
[root@shell2 ~]# echo $[100%3]                               #取余运算
1
[root@shell2 ~]# echo "$?"                                   #正常显示
0
[root@shell2 ~]# echo '$?'                                   #作为输出显示
$?
[root@shell2 ~]# mkdir $(date +%F)                           #创建一个以日期为名的文件夹
[root@shell2 ~]# ll
drwxr-xr-x. 2 root root    6 Jan 22 22:13 2019-01-22

read命令

    · 用途:产生交互的方式,将用户从键盘上的输入,赋予一个变量来存储。

    · 选项:-p,书写屏幕输出信息

                -n 数字,定义输入文本的长度

]# vim useradd.sh

#!/bin/bash
read -p "请输入要创建的用户名:" ming                 #交互式,收集用户输入赋值给变量ming
stty -echo                                        #隐藏输入
read -p "输入用户密码:" mima
stty echo                                         #显示输入
useradd $ming &>/dev/null
echo "用户 $ming 创建成功"
echo $mima | passwd --stdin $ming &>/dev/null     #设置密码
echo "密码设置成功"

]# chmod +x useradd.sh
]# ./useradd.sh

测试命令表达式

   语法:
        ]# [ 测试表达式 ]
        ]# echo $? (检查状态值)
   选项:
    ·检查文档状态(   ]# $[ 选项 路径 ]   )
        -e = 文档存在 为真
        -d = 文档存在且是 目录 为真
        -f = 文档存在且是 文件 为真
        -r = 文档存在且有 读取权限 为真
        -w = 文档存在且有 写入权限 为真
        -x = 文档存在且有 执行权限 为真

    ·比较整数大小(   ]# [ 值A 选项 值B ] )
        -gt :(greater)大于
        -ge :()大于等于
        -eq :(equal)等于
        -ne :(not equal)不等于
        -le :()小于等于
        -lt :(less-than)小于


    ·字符串比对(  # [ $USER == root ]     )
        == : 相等为真
        != : 不等为真

判断字符串中是否包含另一字符串
  [[ $a =~ "b" ]] : 判断变量中是否包含字符串(=~ 代表正则的匹配),变量a中是否包含字符b

分支结构

1.if结构:
    if [ 测试条件 ];then
      执行A
    fi


2.if双分支结构:
    if [ 测试条件 ];then
      执行A
    else
      执行B
    fi

3.if多分支结构:
    if [ 测试条件1 ];then
      执行A
    elif [ 测试条件2 ];then
      执行B
    elif [ 测试条件3 ];then
      执行C
    elif...
      执行...
    else
      执行Z
    fi    
 

例1:
    # vim /root/suiji.sh            #
    /vim/
    #!/bin/bash                #
    read -p '输入一个10以内的数字:' numIn    #
    num=$[ $RANDOM % 10 ]            # $RANDOM=随机数。取余10(不含)以内的数字
    if [ $numIn -eq $num ];then        # 如果 [ 相等 ];然后
      echo '答对了'                #
    else                    # 否则
      echo '错了,正确数字是:'$num        #
    fi                    # 结束finish
    /vim/
    #chmod +x /root/suiji.sh        #
    # /root/suiji.sh            #
    
例2:条件判断语法
    1).如果a>b且a<c
        if (( a > b ))  &&  (( a < c ))        或者
        if [[ $a > $b ]]  &&  [[ $a < $c ]]    或者
        if [ $a -gt $b  -a  $a -lt $c ]            //-a,and    或者
        if [[ $a > $b  &&  $a < $c ]]
    2).如果a>b或a<c
        if (( a > b ))  ||  (( a < c ))        或者
        if [[ $a > $b ]]  ||  [[ $a < $c ]]    或者
        if [ $a -gt $b  -o  $a -lt $c ]            //-o,or    或者
        if [[ $a > $b  ||  $a < $c ]]

for循环

for 变量名 in 值列表

do

    执行命令块

done

[root@server0 ~]# cat  /root/for.sh
#!/bin/bash
for i  in  zhangsan  lisi   wangwu   dc  haha   xixi   duanwu  zhongqiu
do
  useradd  $i  &>  /dev/null
  echo  $i创建成功
done


[root@server0 ~]# cat  /root/for.sh
#!/bin/bash
for i  in  $(cat  /root/tarena.txt)
do
  useradd  $i  &>  /dev/null
  echo  $i创建成功
done

 

转载于:https://my.oschina.net/xinsui1314x/blog/3004814

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值