相关文章推荐

shell脚本编写进度条

shell脚本及执行方式

Shell脚本,是一种为shell编写的脚本程序。shell编程和Java,Python和PHP编程类似,只要有一个可以编写代码的文本编辑器和一个可以解释并执行代码的解释器就可以了。
来看个简单的shell脚本:
touch一个myshell.sh,其中 .sh 是shell脚本的后缀

#!/bin/bash
echo "hello shell!"

在这里解释一下第一行, #! 是一个约定的标记,它告诉系统应该用什么解释器来执行这个脚本。后面的 /bin/bash 就是解释器了。
要执行这个shell脚本有两种方式:

  1. 作为可执行程序
    我们创建的文件默认是没有可执行权限的,利用chmod加上权限就可以执行了
    这里写图片描述

  2. 作为解释器参数
    直接运行解释器,其参数就是 shell 脚本的文件名,以这种方式运行的脚本就不需要在第一行指定解释器信息,写了也没用
    这里写图片描述

来谈谈这两种方式的本质

第一种方式: shell会fork创建一个子进程并调用exec来执行这个脚本程序,而且exec有一种机制,如果要执行的是一个文本文件而且第一行给出了解释器,那么就直接用解释器程序的代码段直接替换当前进程然后开始执行,而这个文本文件被当做命令行参数传给解释器。
第二种方式: 第二种方式也就是将文本文件传给解释器做命令行参数来执行。

需要注意的是:执行某些命令,不一定要创建子进程!这些不需要创建子进程的命令,叫做shell的内置命令,由父bash亲自执行。例如:cd命令就是一个内置命令。

shell变量

shell是弱类型语言,看看下面的例子:

#!/bin/bash
b=3.14
c="hello"
d='m'
echo $a
echo $b
echo $c
echo $d

来看看运行结果:
这里写图片描述
可以看到shell变量中可以放整型、浮点型、字符型、字符串等等很多东西,在这里需要强调的一点是: 变量名和等号直接不能有空格 ,如果带了空格会被shell解释为命令和命令行参数。下面是shell变量的命名规则:

  • 首个字符必须为字母(a-z,A-Z)
  • 中间不能有空格,可以使用下划线(_)
  • 不能使用标点符号
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。
shell变量的使用及删除

当使用一个变量或输出的时候需要在变量名前加 $ 符号,但一般变量赋值的时候不需要使用,也可以给变量名加上花括号 { } ,这样是为了方便解释器识别边界。
如果我们要对变量进行计算时,就需要用双圆括号 (( )) ,双圆括号中的内容是类C的,如下:

#!/bin/bash
c=$((a+b))
echo ${a}
echo ${b}
echo ${c}

如果我们需要删除一个变量就需要用到unset命令:

#!/bin/bash
mystr="hello word"
echo $mystr
unset mystr
echo $mystr

这里写图片描述
被删除的变量内容会被清空,可以看到第二个echo语句输出了一个空串

被readonly修饰的变量时只读变量,不可以修改它的值,同样也不能被删除

#!/bin/bash
readonly mystr="hello word"
echo ${mystr}
mystr="this is string"
echo $mystr
unset mystr
echo $mystr
  1. 本地变量:局部变量在脚本或命令中定义,只存在于当前shell中,其他shell启动的程序不能访问

  2. 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,可以从父进程传给子进程,利用printenv命令可以查看当前shell的环境变量,如果利用export可以将本地变量导出为环境变量

  3. shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

shell条件测试

测试命令test和 [

直接上例子:

#!/bin/bash
read a #从标准输入读入
test $a -eq 100 
echo $?

看最后一条语句,echo $? 是查看上面最近一个程序的退出码,在shell脚本中,测试条件成立退出码为0,不成立为非0
这里写图片描述
除了上面的test还可以利用 [ ] 来进行测试:
注意:在使用 [ ] 的时候每个变量之间要有空格,变量和左右方括号之间也需要有空格,不然就会报错

#!/bin/bash
read a
[ $a -eq 100 ] 
echo $?

这里写图片描述
从上面的例子可以注意到,我们是利用 -eq 来进行比较的,对于不同的类型,测试选项也不同

  • 整数:-eq 等于、-ne 不等于、-le 小于等于、-ge 大于等于、-lt 小于、-gt 大于
  • 字符串:==/=!=-z-n
  • 文件:-d-f-b-c

比较字符串的时候==和=都可以用来判断是不是相等,-z是用来判断一个字符串是否为空串,-n是判断一个字符串是否为非空串。
-d 判断是否为目录;-f 判断是否为普通文件;-b 是否为块设备;-c 是否为字符设备,来看例子:

#!/bin/bash
[ -d / ]            #是否为目录
echo $?
[ -c /dev/tty ]     #是否为块设备
echo $?
[ -b /dev/sda ]     #是否为字符设备
echo $?
[ -f ./myshell.sh ] #是否为普通设备
echo $?
多条件测试
  • -a:逻辑与
  • -o:逻辑或
  • ! :逻辑非
#!/bin/bash
myint=100
#判断myshell.sh是不是普通文件而且myint是否等于200
[ -f ./myshell.sh -a $myint -eq 200 ]
echo $?
#判断myint是否不等于200并取反
[ ! $myint -ne 200 ]
echo $?
#判断myint是否等于100或者myshell.sh是否是普通文件
[ $myint -eq 100 -o -f ./myshell.sh ]
echo $?

条件分支结构语句

if/then/elif/fi

shell脚本的条件语句格式如下:

1.单分支判断语句

if 条件
    条件成立执行的语句

2.双分支判断语句

if 条件
    条件成立执行的语句
    条件不成立执行的语句

3.多分支判断语句

if 条件1;then 
    条件1成立执行的语句
elif 条件2;then
    条件2成立执行的语句
    条件都不成功执行的语句 

来总结一下,shell脚本的条件判断语句是用 if、then、elif、else、fi 这几条命令来实现的,和C语言很类似,但要注意的是后面一定要有fi,shell脚本中控制分支结构结束都要和开头的单词相反,例如,if <–> fi,case <–> esac
还有一点就是如果两条命令写在同一行则需要用 ; 号隔开,一行只写一条命令就不需要写分号了。另外,then后面有换行,但这条命令没写完Shell会自动续行,把下一行接在then后面当作一条命令处理。和 [ 命令一样要注意命令和各参数之间必须用空格隔开
在这里直接上一个多分支的例子:

#!/bin/bash
read data
if [ $data -eq 100 ];then
    echo "this is 100"
elif [ $data -eq 200 ]
    echo "this is 200"
    echo "hello word"

在C语言中如果我们在if中什么都不做就可以写一条空语句 ; 或者什么都不写,但在shell脚本中如果出现空语句就会报错,所以在shell脚本中用 这个空命令,这个命令什么事都不做,但它的退出码总是为真,在这里就不举例子了。

再补充一条:if命令的参数组成了一条子命令,如果该子命令的Exit Status为0(表示真),则执行then后面的子命令。如果Exit Status非 0(表示假),则执行elif、else或者fi后面的子命令。if后面的子命令通常是测试命令,除了 [ 和 test 命令,还可以放其他命令,只要该命令退出码为0,1来表明执行就可以

case/esac

在C语言中有switch/case语句,在shell脚本中有case命令和它的功能是类似的,直接看个例子吧:

#!/bin/bash
read data
case $data in
    "100" )
        echo "this is 100"
    "200" )
        echo "this is 200"
    "300" )
        echo "this is 300"
        echo "default"

C语言的case只能匹配整型或字符型常量表达式,而Shell脚本的case可以匹配字符串和通配符,在匹配完成要在后面加一个 ) ,每个匹配分支可以有若干条命令,最后必须以;;结束,就类似与C语言中的break。而代码中最后一行的 * 就相当于C语言中的default一样。
这里写图片描述

1.while循环

while循环只要while语句为真就执行

while 条件 
#!/bin/bash
i=$1
while [ $i -lt 5 ]
    echo "this is $i"
  # ((i++))
    let i++

看程序中,我们对循环变量做改变的时候,用了两种方式,其中一种是最开始说的双圆括号,还有一种是可以利用 let 命令

2.for循环

shell脚本对for循环有两种:

(1) 类C的写法
同样是利用我们上面的双圆括号,不多做解释了

#!/bin/bash
for ((i=0;i<10;i++))
    echo "hello $i"

这里写图片描述
(2) for in 循环
直接上两个特色的例子:

#!/bin/bash
for i in {a..c}{1..3}
    echo "hello $i"
#!/bin/bash
for i in {a,b,c} {1,2,3}
    echo "hello $i"

可以看到这两段代码的区别就是,第二段代码的两个花括号之间有一个空格,第一个不带空格的是将两个花括号中的内容进行排列组合,而不带空格的话是分别遍历两个花括号中的内容。当然也可以只有一个花括号,花括号中的内容可以像第二个一样枚举出来,也可以类似第一个直接利用 . .

3. until循环

shell还有一种自己特有的循环是until循环
until循环和while循环的写法很像,但是until循环是当条件为假就执行循环体

#!/bin/bash
until [ $i -ge 10 ]
    echo "hello $i"
    let i++

shell函数

看看shell函数的格式:

[function] funcName() 
    [return 返回值] 

shell的函数没有参数列表,[ ]中的内容是可选的,function标识这是一个函数,后面跟函数名。也可以不加function直接写出函数名。shell函数的返回值也是可选的,只能返回整数,如果没有给出return,则默认返回最后一条语句的执行结果

#!/bin/bash
function myfun()
    echo "this is a function!"
    return 1
myfun

shell在定义函数时并不执行函数体中的命令,就像定义变量一样,只是给myfun这个名字一个定义, 到后面调用 myfun函数的时候才执行函数体中的命令。shell脚本中调用函数不用带括号,而且shell函数必须先定义再调用
这里写图片描述

shell函数虽然没有参数列表,但是依然可以给它传参。来看看下面的例子:

#!/bin/bash
function myfun()
    echo "this is function"
    echo $0
    echo $1
    echo $2
    echo $#
    echo $@
    echo "this is function!"
myfun str1 str2

shell在调用函数的时候可以在函数后面跟上参数,在函数体内部就可以利用之前说过的获取命令行参数的方法来拿到函数参数
这里写图片描述
解释一下这些变量:

  • $0:文件名,相当于C语言main函数的argv[0]
  • $1:第一个参数,相当于argv[1]
  • $#:参数个数
  • $@:参数列表
Shell 脚本,是一种为 shell 编写的脚本程序。shell编程和java、Python、PHP编程类似,只要有一个可以编写代码的文本编辑器和一个可以解释并执行代码的解释器就可以了。 来看个简单的shell脚本:...
#shell判断文件夹是否存在 #如果文件夹不存在,创建文件夹if [ ! -d "/myfolder" ]; then mkdir /myfolderfi #shell判断文件,目录是否存在或者具有权限 folder="/var/www/"file="/var/www/log" # -x 参数判断 $folder 是否存在并且是否具有可执行权限if [ ! -x "$folder"];...
基本语法[ condition ] #注意前后空格#非空返回true  常用判断条件1) 两个值比较= 字符串比较-lt less than-le less or equal-eq equal-gt greater than-ge greater or equal-ne not equal#!/bin/bash if [ 20 -gt 10 ] echo "20 ...
因为shell比较简单,需要的语句可以随时上网查,这篇工具书不准备进行详尽的编写,只是记录简单的几个例子,以便将来有需要的时候拿来用。 1.1 运行 执行当前目录下的myShell.sh文件 sh ./myShell.sh 2. 案例集合 2.1 创建目录及循环创建文件 #!/bin/sh mkdir shell_test cd shell_test for ((i=0; i<10; i++)); do touch test_$i.txt 2.2 循环进入目录并创建文件 整个过程感觉比较顺利,出现了两个小插曲。 增强功能进行到最后一步输入密码时我发现屏幕上没有显示,以为出错,但是不知哪里出了问题。于是求助室友大大,她给了我一个链接某链接 按照这种方法安好了。不过后来再看了课程后了解到Linux输入密码是不会显示的。 由于我对搜狗中文输入法的执着,我用虚拟机按照以前的方式下载搜狗,但是出现如图情况 然后我搜了一下,默认...
Shell Shell 简介 Shell一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 Shell 常用命令 -e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L filename 如果 filename为符号链接,则为真 -r filename 如果 filename可读,则...
使用xftp上传Hadoop、Spark、Zookeeper 解压Hadoop、Spark、Zookeeper、JDK tar zxf /h3cu/hadoop-2.6.0.tar.gz -C /usr/local/src tar zxf /h3cu/spark-2.0.2-bin-hadoop2.6.tgz -C /usr/local/src tar zxf /h3cu/jdk-8u231-linux- -- SQL注释 (--空格) update mysq1.user set authentication_string=password('123456') where user='root' and Host =' loca1host'; -- 修改用户密码 flush privileges; -- 刷新权限 数据库xxx语言 CRUD增删改查 DDL定义 DML操作 DQL查询 DCL控制 操作数据库 -- 加个数据库 create database if not e