加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

shell编程基础篇

发布时间:2020-12-15 18:20:10 所属栏目:安全 来源:网络整理
导读:重点注意,我们这里介绍的是CentOS 6.7 版本的Linux 一、shell的介绍 ?(1)什么是shell? ????? ??shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出的结果,输出到屏幕返回
重点注意,我们这里介绍的是CentOS 6.7 版本的Linux

一、shell的介绍

?(1)什么是shell?

?????


??shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出的结果,输出到屏幕返回给用户。这种对话方式可以是交互式的(从键盘输入,立刻得到shell的回应),或者非交互式的。Shell:是一门弱类型(语法叫宽松)的语言较为通用的shell有bash shell。shell脚本语言的种类也比较多:Bourne shell (包括:sh,ksh,and bash)、C Shell (包括:csh and tcsh)。当然我们这里主要说的是bash shell!!!!!

?(2)shell的编写规范

?? - 脚本的开头第一行为:#!/bin/bash 或者 #!/bin/sh。这是因为#!又称为幻数,在执行bash脚本的时候,内核会根据它来确定该用哪一个程序来解释脚本中的内容,这一行必须在脚本的顶端的第一行。其实bash和sh是一个文件,只不过在Linux中/bin/sh是一个链接文件实际的指向为/bin/bash。
?? - 如果在脚本的第一行没有指定解释器,在运行的时候需要使用bash命令执行。
?? - 开头加入版权、作者等信息(只是一个建议而已)
?? - 脚本中尽量不要使用中文
?? - 脚本名称尽量以.sh结尾
?? - 尽量添加多的注释,这样对调试和其他人使用脚本都有帮助。

?(3)shell的注释

?? - 单行注释:“#”
?? - 多行注释:“:<<! !:”

?(4)脚本的执行?

?? 在Linux下执行shell有三种方式:
?? - bash / sh 执行shell脚本
?? - path/script.sh 直接执行脚本(脚本必须是可执行文件,并且首行有解释器标识)
?? - source script.sh或者. script.sh 这种方式可以将自身脚本中的变量的值或者函数等的返回值传递到父shell中执行。(当前操作的shell(父)---编写的脚本执行(子)),也相当于父shell将子shell的脚本中命令读取到自己的shell中然后执行。

二、shell中的变量

?(1)shell的变量介绍

??shell中的变量分为两类:环境变量(全局变量)和局部变量
???环境变量:在创建他们的shell以及派生出来的任意子进程的shell中均可以使用。
???局部变量:只能在创建他们的shell函数或者脚本中使用。

?(2)环境变量

?? 用于定义shell的运行环境,保证shell的正确执行。所有的环境变量都是系统的全局变量可以用于所有子进程中,包括编辑器、shell脚本和各类应用。
?? 例:

#声明
        export 变量名 = 变量的值
        变量名=变量的值;export 变量名
        declare -x 变量名=变量的值
#系统内置的环境变量介绍:
$HOME       用户的家目录
$USER        当前用户
$UID         当前用户的uid
$SHELL       当前用户使用的shell
$HISTISZE     记录在命令行历史文件中的命令行数
$PATH        执行命令时寻找的目录
$PWD        当前用户的家目录
$PS1          用户登录的环境变量  [[email?protected] ~]
$TMOUT       用户登录的超时时间
#显示和取消环境变量
显示:echo $变量
set和env 显示所有的环境变量。
取消:unset 变量名。
readonly:设置只读变量

?(3)局部变量

?? 局部变量也成为本地变量,在用户当前的shell中使用,如果退出shell,则失效。
??例:

#声明:
变量名=value(数字、字母、下划线组成)

这里需要介绍一下Linux下的双引号、单引号和不加引号的区别:


由上面的例子可以看出:
单引号:所见即所得,单引号内的内容原样输出。
双引号:如果内容中有变量等,会将变量解析出来,然后将最终的结果打印
不加引号:把内容输出出来,如果有连续的空格会将空格合并为一个空格,然后将变量等解析出来在输出。
反引号:把字符串当做命令去执行。


注意:一般的在使用命令的时候,变量的引用尽量不要加引号或双引号。但是在做字符串判断的时候一般的都需要加上引号。

?(4)特殊变量

#介绍
$0:表示获取当前脚本的脚本名、
$n:获取当前执行的shell脚本的第n个参数,n=1..9,如果n大于10,用${10}
$#:获取当前shell命令行中参数的个数
$*:表示参数列表
[email?protected]:表示参数列表
$$:获取当前shell的进程号
$!:执行上一个指令的PID
$?:获取执行的上一个指令的返回值(0表示成功,非零表示失败)
$_:在此之前执行的命令或脚本的最后一个参数

具体的小编在这里给大家补充两点:
?? - $*和[email?protected]的区别


大家可以运行上面的脚本并传入参数,看看具体如何打印的,就大概明白两者的区别了。
?? - $?返回值得介绍(有助于错误排查):

0:表示执行成功
            2:权限拒绝
            1~125:表示运行失败,脚本命令,系统命令,错误或者参数传递错误
            126:找到该命令,但是无法执行
            127:未找到该命令
            大于128:命令被系统强制停止

三、shell变量的进阶操作

(1)shell变量的计算

?? 好的shell脚本,变量的计算显然是离不开的,可以使用(())、let、expr、bc、$[]变量进行计算,这里给大家总结几个常用的。

?? (()):

?? ?只能用于整数计算。常用,效率高。

#用法
a=$((1+1));   需要使用$进行修饰
((a=1+1))   此种方式不需要用$修饰
a=((3>1))    也可以写入比较,正确返回1,错误返回0
#实现简单的计算器:
#!/bin/sh
read -p "Please input first num:" num1
read -p "Please input operators:" operators
read -p "Please input second num:" num2
sum=$(($num1$operators$num2))
echo "$num1 $operators $num2 = $sum"

?? let:

?? ?用作简单的整数计算,let赋值表达式。
#例:

[[email?protected] zy]# i=2
[[email?protected] zy]# i=i+8 #表示字符串的拼接
[[email?protected] zy]# echo $i #打印i+8
[[email?protected] zy]# i=2
[[email?protected] zy]# let i=i+8 #表示数值计算
[[email?protected] zy]# echo $i #打印10

?? bc:

?? ?可以实现整数、小数的运算,接受标准输入。

[[email?protected] zy]# i=2
[[email?protected] zy]# echo "$i+2.4"|bc #打印4.4

#实现1+2…10的计算
#!/bin/sh
str=""
for i in `seq 10` 
  do
    if [ $i -eq 10 ];then
      str=$str$i
    else
      str=$str$i"+"
    fi
  done
sum=`echo "$str"|bc`
echo "$str=$sum"

#保留小数

[[email?protected] zy]# echo "scale=2;3.14/2.1"|bc #保留两位小数

?? $[]:

?? ?a=$[1+1],与(())类似,但是[]不能讲变量提取到[]中。

(2)变量子串的常见操作

#子串的操作
${#string}      返回string这个变量的长度
${strting:position} 在变量string中从position开始提取子串(从0开始,取到结尾)
${string:pos:len}   在变量string中从pos开始提取子串,提取长度为len
${string#sub}   在变量string中从头开始,删除sub匹配的子串
${string%sub}   在变量string中从末尾开始,删除sub匹配的子串
${string/old/new}   在变量string中将old内容,替换成new(只替换第一个找到的)
${string//old/new}  在变量string中将old内容,替换成new(替换所有找到的内容)
${value:=word}  给变量赋默认值,LOD=${value:=word},$LOD的值为word
${value:index:len}  从index位置开始取值,向后取len长度
#变量的替换
${value:-word}  当value定义或者为空时,返回后面的值,当value已经有值了就返回value的值,只是针对返回值,value本身仍然没有值    
#例:
result=${value:-word}
echo $result    #打印word
echo $value   #打印空

${value:=word}  当value定义或者为空时,返回后面的值,value的值也会改变,当value已经有值了就返回value的值,#例:
result=${value:=word}
echo $result    #打印word
echo $value   #打印word

${value:?”not default”} 如果变量名存在且非空,则返回变量的值,否则显示“变量名:message“,并退出当前脚本    
#例:
[[email?protected] zy]# ${key:?"not default"} #打印 -bash: key: not default

${value:+word}  如果变量存在且不为空,则返回后面的值,否则返回null。用于测试变量是否存在  
#例:
[[email?protected] zy]# echo ${result:+word}  #打印:word(已定义)
[[email?protected] zy]# echo ${key:+word} #打印 空 (未定义)

${result-value} 与${value:-word}相同

这里给大家介绍一个具体的例子看看,变量操作的重要意义:

#将某目录下的所有.jpg的文件改成,以.JPG的结尾
#方法一:
for i in `ls *.jpg`;do mv $i ${i/%jpg/JPG} ; done;
#方法二:
rename .jpg .JPG *
#计算变量的长度
#方法一:
[[email?protected] zy]# echo ${#chars}
#方法二:
[[email?protected] zy]# echo $chars|wc –c  #会多打印末尾的换行
#方法三:
[[email?protected] zy]# echo $(expr length "$chars")
#方法四:
echo $value|awk -F’’ ‘BEFORE{count=0}  {count++}  END{print count}’

看似不使用变量操作,就可以使用命令解决我们的问题,但是执行的效率呢?
我们可以在命令前加上time 查看命令执行的时间:
[[email?protected] ~]# time for i in seq 1111 ;do count=${#chars};done;


同样的可以查看上面所有的方法的执行时间,一对比,就只到变量操作的强大体现在哪里。这里小编给大家总结一下(以前三种方法为例):方法一>方法三>方法二 #最终使用内置的功能效率最高

四、shell中通用常用命令介绍

(1)echo命令

???对于这个命令大家可能熟悉的不能再熟悉了,将指定内容显示到标准输出。
?例:

[[email?protected] my_test]# echo "abc" #会打印 abc
[[email?protected] my_test]# echo -n "abctabc" #会打印 abctabc
[[email?protected] my_test]# echo -e "abctabc" #会打印 abc abc
[[email?protected] my_test]# echo -n "abc" #默认的echo命令是打印之后换行,-n表示不换行

(2)eval命令

???读入参数,将他们组成一个新命令执行

[[email?protected] my_test]# eval "echo " "1" #打印1

(3)exec命令

???当shell执行到exec语句时,不会去创建新的子进程,而是转去执行命令,当指定的命令执行完成后,shell就结束了,所以exec后的命令不会执行。

#脚本
#!/bin/sh
echo "before exec"
exec echo "exec run"
echo "after exec"

结果exec 语句之后的命令就不会执行了,而且退出了当前的shell

(4)export命令

???将申明的变量导出,成为全局变量。

(5)read命令

???从标准输出中读取字符串,传递给变量.

#介绍:
-p  设置提示信息,例:read –p “请输入:” value
-t time(second),设置超时时间。例:read –t 3 –p“请输入胡” value

(6)shift命令

???shift语句按如下方式重命名所有的位置变量,如,$2变成$1,$3变成$2…,即在程序中每使用一次shift命令,都使得所有的位置信息依次向左移动一个位置。$#也会依次减少,直到为0
?例:

#!/bin/sh
# script-name : test.sh
echo $# 
shift 
echo $# 
shift 
echo $# 
shift

[[email?protected] my_test]#sh test.sh 1 2 3 #最终会打印 3 2 1

(7)exit命令

???表示退出当前的shell脚本,后面可接参数,0:表示正常退出,非零表示异常退出。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读