shell脚本

输出重定向

【>】                                                   # 先创建文件再导出,多次定向会覆盖内容

[root@localhost ~]# ls

1.txt

[root@localhost ~]# ls > 2.txt              # 过程:创建2.txt-----显示1.txt和2.txt-----把1.txt和2.txt作为内容导给2.txt这个文件

[root@localhost ~]# ls

1.txt 2.txt

[root@localhost ~]# cat 2.txt

1.txt

2.txt

【>>】                                                  # 先创建文件再导出,多次定向会追加内容

[root@localhost ~]# ls

1.txt

[root@localhost ~]# ls >> 2.txt              # 过程:创建2.txt-----显示1.txt和2.txt-----把1.txt和2.txt作为内容导给2.txt这个文件

[root@localhost ~]# ls

1.txt 2.txt

[root@localhost ~]# cat 2.txt

1.txt 2.txt

[root@localhost ~]# ls >> 2.txt              # 再次定向会追加内容,而不是覆盖内容

[root@localhost ~]# cat 2.txt

1.txt

2.txt

1.txt

2.txt

【2>】 【2>>】                                                    #错误输出重定向

[root@localhost ~]# ls wmc.txt

ls: 无法访问wmc.txt: 没有那个文件或目录

[root@localhost ~]# ls wmc.txt > b.txt

ls: 无法访问wmc.txt: 没有那个文件或目录

[root@localhost ~]# ls wmc.txt 2> b.txt

[root@localhost ~]# cat b.txt                                   #b.txt文件的内容中有报错输出

ls: 无法访问wmc.txt: 没有那个文件或目录

【&>】 【&>>】                                                      #正确输出和错误输出一起重定向

[root@localhost ~]# ls 1.txt wmc.txt

ls: 无法访问wmc.txt: 没有那个文件或目录

1.txt

[root@localhost ~]# ls 1.txt wmc.txt > b.txt                    #正确输出导入b.txt,错误输出留下

ls: 无法访问wmc.txt: 没有那个文件或目录

[root@localhost ~]# ls 1.txt wmc.txt 2> b.txt                 #错误输出导入b.txt,正确输出留下

1.txt

[root@localhost ~]# ls 1.txt wmc.txt &> b.txt                 #正确输出和错误输出一起重定向 [root@localhost ~]# cat b.txt

ls: 无法访问wmc.txt: 没有那个文件或目录

1.txt

一个合格规范的脚本应该包含以下这些内容

①#!脚本声明(使用哪种解释器解释代码)

②注释信息(步骤、思路、用途等),以#开始的为注释信息

③可执行的语句

[root@localhost ~]# vim first.sh

#!/bin/bash

#A test program for Shell.

echo "Hello World"

[root@localhost ~]# chmod +x first.sh

[root@localhost ~]#/root/first.sh

执行脚本的多种方式

方法一,需要为文件赋予可执行的权限

#[root@localhost ~]# chmod +x first.sh

-绝对路径执行

-相对路径执行

方法二,不需要文件有可执行的权限

sh/bash 脚本文件名

source 脚本文件名 #不会启动子进程,通过pstree查看进程树

变量

定义变量

以固定的名称,存放可以能有变化的 

定义变量的格式: 变量名=变量值

取消变量的格式: unset 变量名

注意事项 =两边不能有空格,不要使用关键字做变量名,如Is、cd等

如果变量名已经存在则覆盖之前的变量值

变量名称有:字母/数字/下划线组成,不能以数字开始

[root@localhost ~]# a=11

[root@localhost ~]# echo $a

11

[root@localhost ~]# echo $a33 #用{}包裹变量,后面可加其他,否则可能引起识别错误

[root@localhost ~]# echo ${a}33

1133

变量类型

环境变量 (变量名通常大写,有操作系统维护)

位置变量 (bash内置变量,存储脚本执行时的参数)

预定义变量(bash内置变量,可以调用但是不能赋值或修改)

自定义变量 (用户自主设置)

环境变量

-存储在/etc/profile或~/.bash_profile

-命令env可以列出所有环境变量

-常见环境变量: PATH、PWD、USER、UID、HOME、SHELL

[root@localhost~]#echo $PATH

[root@localhost~]# echo $UID

位置变量 -存储脚本执行时的参数

使用$n表示,n为数字序列号

$1、$2、...、${10}、${11}、...

[root@localhost ~]# vim useradd.sh

#!/bin/bash

useradd "$1" echo "$2" | passwd --stdin "$1"

[root@localhost ~]# sh useradd.sh lisi 123123

更改用户 lisi 的密码。

 passwd:所有的身份验证令牌已经成功更新。

[root@localhost ~]# tail -1 /etc/passwd

lisi❌1001:1001::/home/lisi:/bin/bash

预定义变量

用来保存脚本程序的执行信息

-直接使用这些变量

-不能直接为这些变量赋值

$0 当前所在的进程或脚本名

$$ 当前运行进程的PID号

$? 命令执行后的返回状态,0表示正常,1或其他值表示异常

$# 已加载的位置变量的个数

$* 所有位置变量的值

多种引号的区别

区分三种定界符

-双引号””:允许扩展,以$引用其他变量

-单引号'':禁用扩展,即便$也视为普通字符

-反引号:将命令的执行输出作为变量值,$()与反引号等效

[root@localhost ~]# aa=`tail -1 /etc/passwd`          #输出作为变量

[root@localhost ~]# echo $aa

lisi❌1001:1001::/home/lisi:/bin/bash

read标准输入取值

read 从键盘读入变量值完成赋值

格式:read [-p”提示信息”] 变量名

-p可选,-t可指定超时秒数,-s设置是否在终端显示输入的内容

[root@localhost ~]# read -p "请输入姓名:" name

请输入姓名:lisi

[root@localhost ~]# echo $name

lisi

[root@localhost ~]# vim read.sh

#!/bin/bash

read -p"请输入用户名:" name

read -p"请输入密码:" pass                      #-s不在终端显示输入的内容

useradd "$name" echo "$pass" | passwd --stdin $name

[root@localhost ~]# sh read.sh

请输入用户名:zhangsan

请输入密码:123123

更改用户 zhangsan 的密码 。

passwd:所有的身份验证令牌已经成功更新。

-局部变量 #如x=11 新定义的变量默认只在当前Shell环境中有效,无法在子Shell环境中使用全局

-全局变量 #如export x=11 全局变量在当前Shell及子Shell环境中均有效

shell中的运算

基本运算法则

-加法:num1 + num2

-减法:num1- num2

-乘法:num1 * num2

-整除:num1 / num2

-取余:num1% num2

简写表达式 完整表达式

i++               i=i+1

i--                i=i-1

i+=2            i=i+2

i-=2              i=i-2

j=2                i=i2

i/=2              i=i/2

i%=2            i=i%2

$[]算式替换

使用$[]或$(())表达式   let不显示结果 expr \

-格式:$[整数1 运算符 整数2....]

-计算结果替换表达式本身,可结合echo命令输出

[root@localhost ~]# echo $[1+2]

3

[root@localhost ~]# echo $[5%3]

2

[root@localhost ~]# echo $[5/3]

1

[root@localhost ~]# x=1 y=2

[root@localhost ~]# echo $[x+y]

3

小数运算

echo "scale=n(几位小数) ;浮点运算" |bc scale=n(几位小数)

awk ' BEGIN{print 浮点运算} '

条件测试操作

test 【选项】【参数】 / [ 选项 参数 ]

字符测试

-z 是否为空

= 等于

!= 不等于

-n 是否有字符串存在

文件状态测试

[操作符 文件或目录]

-e 判断对象是否存在(Exist),若存在则结果为真

-d 判断对象是否为目录(Directory),是则为真

-f 判断对象是否为一般文件(File),是则为真

-r 判断对象是否有可读(Read)权限,是则为真

-w判断对象是否有可写(Write)权限,是则为真

-x对象是否有可执行(Xcute)权限,是则为真

整数值比较

[整数值1 操作符 整数值2] / (( ))

-eq 等于(Equal)

-ne 不等于(Not Equal)

-ge 大于或等于(Greater or Equal)

-le 小于或等于(Less or Equal)

-gt大于(Greater Than)

-It 小于(Less Than)

控制符:组合命令

; 命令1 ;命令2 ;命令n...                    #顺序执行,命令间无逻辑关系。

-a或&& 命令1 && 命令2 && 命令n...       #顺序执行,命令间有逻辑关系,仅当前一条命令执行成功,后续才会执行,否则停止执行。

-o或|| 命令1 || 命令2 || 命令n...                #顺序执行,命令间无逻辑关系,前一条命令执行失败,后续执行。前一条命令执行成功,后续不执行。

if 语句

-if 单分支

if 条件测试 / 【表达式】 && a

then

      命令序列

fi

[root@localhost ~]# vim read.sh

#!/bin/bash

read -p"请输入用户名:" name

read -p"请输入密码:" pass

if [ ! -z "$name" ] && [ ! -z "$pass" ]

then

       useradd "$name" echo "$pass" | passwd --stdin $name

fi

echo                                                                #输入的用户或密码任一为空时,创建用户不成功

-if 双分支

if 条件测试 【表达式】 && a || b

then

       命令序列1

else

      命令序列2

fi

[root@localhost ~]#vim ping.sh

#!/bin/bash if [ -z "$1" ]

then

        echo -n "用法:脚本 "

        echo -e "\033[32m域名或IP\033[0m"

        exit

fi

ping -c2 -i0.1 -W1 "$1" &>/dev/null

if [ $? -eq 0 ]

then

        echo "$1 is up"

else

        echo "$1 is down"

fi

-if 多分支

if 条件测试 1

then

       命令序列1

elif

       条件测试2

then

       命令序列2

.... ........

else

命令序列n

fi

for 循环

-根据变量的不同取值,重复执行命令序列

for 变量 in 值列表

do

     命令序列

done

#!/bin/bash                        #批量创建用户

for i in {1..10}                    #$(cat user.txt)把用户名写入文件中调用

do

     useradd test$i echo "995620" | passwd --stdin tast$1

done

for((初值;条件;步长))

do

     命令序列

done

[root@localhost ~]# vim 99.sh                          # 打印99乘法表

#!/bin/bash

for ((i=1;i<=9;i++))

do

     for ((j=1;j<=i;j++))

do

      echo -en "$j$i=$[ij]\t"

done

echo

done

while 循环

while 条件测试

do

     命令序列

done

[root@localhost ~]# vim while.sh                          #打印1-5

#!/bin/bash

i=1

while [ $i -le 5 ]

do

    echo $i

let i++

done

[root@localhost ~]# vim while2.sh                              #创建用户

#!/bin/bash

a=user ; i=1

while [ $i -le 5 ]

do

      useradd ${a}$i echo "995620" | passwd --stdin ${a}$i

let i++

done 、

case语句

case 变量 in

模式1)

           命令序列1 ;;

模式2)

           命令模式2 ;;

...... *)

           默认命令序列

esac

数组

数组也是变量,是存储多个数据的集合。

[root@localhost ~]# test=(aa bb cc)

[root@localhost ~]# echo ${test[1]}

bb

shell函数

在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数。

function 函数名 {                            函数名 (){

命令序列                                        命令序列

}                                                       }

中断与退出

exit 退出shell脚本进程,exit执行后,脚本后面所有的语句都不会执行

break 跳出单层循环,break 2 跳出2层循环,循环内break后面的语句不会执行,但是循环外的语句仍然会执行

continue 终止某次循环的执行,但不会完全终止整个循环 ,while until 循环中使用需要慎重!因为如果continue放在变量迭代语句前面会造成死循环

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值