shell编程大全

一、shell脚本

shell脚本语言是解释性语言,其本质是shell命令的有序集合。

shell脚本在此处有讲解

二、shell编程步骤

  • 创建shell文件
    vi shell.sh

  • 更改权限
    chmod 777 shell.sh

    0	7	7	7           6  6  6
        rwx rwx rwx         rw-rw-rw- 
        111 111 111		   110110110
    
  • 执行shell脚本
    ./shell.sh

三、shell变量

定义变量

variable=value
variable='value'
variable="value"
#variable 是变量名,value 是赋给变量的值。如果 value 不包含任何空白符(例如空格、Tab 缩进等),那么可以不使用引号;如果 value 包含了空白符,那么就必须使用引号包围起来。使用单引号和使用双引号也是有区别的,稍后我们会详细说明

注意:
赋值号=的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。
定义变量时尽量全部大写,避免与命令同名(规定)。
shell变量没有数据类型。

使用变量

#使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:
author="张三"
echo $author
echo ${author}
#变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
skill="Java"
echo "I am good at ${skill}Script"
#如果不给 skill 变量加花括号,写成echo "I am good at $skillScript",解释器就会把 $skillScript 当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。推荐给所有变量加上花括号{ },这是个良好的编程习惯。

注意:
let 表达式 可以让表达式以c语言的风格计算。eg:let sum+=i ;let ++i;

`` 用在两条命令时让被小引号包裹的内容会先执行。eg:echo `expr $sum + 1`

修改变量的值

#已定义的变量,可以被重新赋值,如:
url="ABC"
echo ${url}
url="abc"
echo ${url}
#第二次对变量赋值时不能在变量名前加$,只有在使用变量时才能加$。

单引号和双引号的区别

url="ABC"
out1='输出:${url}'
out2="输出:${url}"
url="输出:${url}"
echo $out1
echo $out2

#运行结果:
#输出:${url}
#输出:ABC

#以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

#以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

将命令的结果赋值给变量

#Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:

variable=`command`
variable=$(command)

只读变量

使用 readonly
下面的例子尝试更改只读变量,结果报错:运行脚本,结果如下:

myUrl="ABC"
readonly myUrl
myUrl="abc"
#运行结果:myUrl: This variable is read only.

删除变量

使用 unset

unset variable_name

#变量被删除后不能再次使用;unset 命令不能删除只读变量。

#举个例子:
myUrl="ABC"
unset myUrl
echo $myUrl

#上面的脚本没有任何输出

四、shell数组

定义数组

#在 Shell 中,用括号( )来表示数组,数组元素之间用空格来分隔。由此,定义数组的一般形式为:
array_name=(ele1  ele2  ele3 ... elen)	#	=号两端不能有空格

#Shell 是弱类型的,它并不要求所有数组元素的类型必须相同,例如:
arr=(20 56 "ABC")	#前面两个元素都是整数,而第三个元素是字符串

#Shell 数组的长度不是固定的,定义之后还可以增加元素。
arr[6]=88

#此外,你也无需逐个元素地给数组赋值,下面的代码就是只给特定元素赋值:
arr=([3]=24 [5]=19 [10]=12)

数组操作

#访问数组元素 index 是数组下标
${array_name[index]}
#给数组元素赋值
array_name[index]=6
#求数组元素个数
${#array_name[@]}或者${#array_name[*]}
#遍历数组元素
${array_name[@]}或者${array_name[*]}

五、shell特殊变量

$$:当前进程的进程号(PID),对于 Shell 脚本,就是这些脚本所在的进程ID
$! :功能描述:后台运行的最后一个进程的进程号(PID)
$?:功能描述:最后一次执行的命令的返回状态,或函数的返回值
$#:传递给脚本或函数的参数个数
$*:传递给脚本或函数的所有参数
$@: 传递给脚本或函数的所有参数,被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到
$0:当前脚本的文件名
$1 - $9 :命令行的第一个到第九个参数

$*与$@的区别

$*和$@都可以用来轻松访问所有的参数,只不过$*会将这些参数视为一个整体,而不是多个个体。$@会将所有参数当作同一字符串中的多个独立的单词

echo "Usint the \$* method: $*"
echo "Using the \$@ method: $@"

count=1
for param in "$*"
do
    echo "\$* params #$count = $param"
    count=$[ $count + 1 ]
done

count=1
for param in "$@"
do
    echo "\$@ params #$count = $param"
    count=$[ $count + 1 ]
done

#执行结果
Usint the \$* method: a b c
Usint the \$* method: a b c
$* params #1 = a b c
$@ params #1 = a
$@ params #2 = b
$@ params #3 = c

六、shell环境变量

了解环境变量

环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或多个应用程序将使用到的信息。Linux是一个多用户的操作系统,每个用户登录系统时都会有一个专用的运行环境,通常情况下每个用户的默认的环境都是相同的。这个默认环境就是一组环境变量的定义。每个用户都可以通过修改环境变量的方式对自己的运行环境进行配置。

常用的几个环境变量:

PATH

指定命令的搜索路径。通过设置环境变量PATH可以让我们运行程序或指令更加方便。

echo $PATH 查看环境变量PATH。

每一个冒号都是一个路径,这些搜索路径都是一些可以找到可执行程序的目录列表。当我们输入一个指令时,shell会先检查命令是否是内部命令,不是的话会再检查这个命令是否是一个应用程序。然后shell会试着从搜索路径,即PATH中寻找这些应用程序。如果shell在这些路径目录里没有找到可执行文件。则会报错。若找到,shell内部命令或应用程序将被分解为系统调用并传给Linux内核。

举个例子:
现在有一个c程序test.c通过gcc编译生成的可执行文件a.out(功能:输出helloworld)。我们平常执行这个a.out的时候是使用三种方法:
1.相对路径调用: ./a.out (”.”代表当前目录,”/”分隔符)
2.绝对路径调用:/home/lzk/test/a.out
3.通过设置PATH环境变量,直接用文件名调用: a.out (只要可以通过PATH中路径找得到这个可执行文件)

HOME

指定用户的主工作目录,即为用户登录到Linux系统中时的默认目录,即“~”。

HISTSIZE

指保存历史命令记录的条数。我们输入的指令都会被系统保存下来,这个环境变量记录的就是保持指令的条数。一般为1000。
这些历史指令都被保存在用户工作主目录“~”下的隐藏文件.bash_profile中。
我们可以通过指令history来查看。

LOGNAME

指当前用户的登录名。

HOSTNAME

指主机的名称。

SHELL

指当前用户用的是哪种shell。

LANG/LANGUGE

和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。

MAIL

指当前用户的邮件存放目录。

PS1

第一级Shell命令提示符,root用户是#,普通用户是$。

PS2

第二级命令提示符,默认是“>”。

PS3

第三级命令提示符。主要用于select循环控制结构的菜单选择提示符 :【等待一个链接】。

TMOUT

用户和系统交互过程的超时值。
系统与用户进行交互时,系统提示让用户进行输入,但用户迟迟没有输入,时间超过TMOUT设定的值后,shell将会因超时而终止执行。

小结

环境变量是和shell紧密相关的,用户登录系统后就启动了一个shell,对于Linux来说一般是bash(Bourne Again shell,Bourne shell(sh)的扩展),也可以切换到其他版本的shell。

bash有两个基本的系统级配置文件:/etc/bashrc和/etc/profile。这些配置文件包含了两组不同的变量:shell变量和环境变量。shell变量是局部的,而环境变量是全局的。环境变量是通过shell命令来设置。设置好的环境变量又可以被所以当前用户的程序使用。

七、shell的功能语句

read

从终端读取一行数据,写入read后的变量
read var var1 var2

expr

算术运算
tmp=`expr $I + 1`
注意:乘法运算符:\*

test

test可理解的表达式类型分为四类:

判断表达式

if test ------(表达式为真)
if test !------表达式为假
test 表达式1 –a 表达式2------两个表达式都为真
test 表达式1 –o 表达式2------两个表达式有一个为真

判断字符串

test –n 字符串------字符串的长度非零
test –z 字符串------字符串的长度为零
test 字符串1=字符串2------字符串相等
test 字符串1 !=字符串2------字符串不等

判断整数

test 整数1 –eq 整数2------整数相等
test 整数 1 –ge 整数2------整数1大于等于整数2
test 整数1 –gt 整数2------整数1大于整数2
test 整数1 –le 整数2------整数1小于等于整数2
test 整数1 –lt 整数2------整数1小于整数2
test 整数1 –ne 整数2------整数1不等于整数2

判断文件
test File1 –ef File2------两个文件具有同样的设备号和i结点号
test File1 –nt File2------文件1比文件2 新
test File1 –ot File2------文件1比文件2 旧
test –b File------文件存在并且是块设备文件
test –c File------文件存在并且是字符设备文件
test –d File------文件存在并且是目录
test –e File------文件存在
test –f File------文件存在并且是正规文件
test –g File------文件存在并且是设置了组ID
test –G File------文件存在并且属于有效组ID
test –h File------文件存在并且是一个符号链接(同-L)
test –k File------文件存在并且设置了sticky位
test –b File------文件存在并且是块设备文件
test –L File------文件存在并且是一个符号链接(同-h)
test –o File------文件存在并且属于有效用户ID
test –p File------文件存在并且是一个命名管道
test –r File------文件存在并且可读
test –s File------文件存在并且是一个套接字
test –t File------文件描述符是在一个终端打开的
test –u File------文件存在并且设置了它的set-user-id位
test –w File------文件存在并且可写
test –x File------文件存在并且可执行

注意:

test xxx 可以简写成 [ xxx ] 的形式。

在使用"[]"简写test时,左括号后面的空格和右括号前面的空格是必需的,如果没有空格,Shell不可能辨别表达式何时开始何时结束.

也就是说:test option file
可以全部改写成:[ option file ]

例如::test –w File
改写成:[ –w File ]

八、shell函数

函数定义

#第一种--如果你嫌麻烦,函数定义时也可以不写 function 关键字
name() 
{
    statements
    [return value]
}
#第二种--如果写了 function 关键字,也可以省略函数名后面的小括号
function name 
{
    statements
    [return value]
}

#建议使用第二种,这样能够做到"见名知意"

函数调用

调用 Shell 函数时可以给它传递参数,也可以不传递。如果不传递参数,直接给出函数名字即可

name

如果传递参数,那么多个参数之间以空格分隔

name param1 param2 param3

不管是哪种形式,函数名字后面都不需要带括号。
和其它编程语言不同的是,Shell 函数在定义时不能指明参数,但是在调用时却可以传递参数,并且给它传递什么参数它就接收什么参数。
Shell 也不限制定义和调用的顺序,你可以将定义放在调用的前面,也可以反过来,将定义放在调用的后面。

示例:

function getsum
{
    local sum=0
    for n in $@
    do
         ((sum+=n))
    done
    return $sum
}

getsum 10 20 55 15  #调用函数并传递参数
echo $?

#在函数内shell特殊变量就由调用函数时传入的参数决定
#函数返回值,只能通过$?系统变量获得,直接通过=获得是空值,可以把函数理解成一个命令
#在shell中获得命令返回值,都需要通过$?获得

九、shell结构性语句

条件测试语句

if ... then ... fi
if 表达式
then
	命令表
fi
#如果表达式为真,则执行then 后的命令表	
if ... then ... else ... fi
if 表达式
then 命令表1
else 命令表2
fi
#如果表达式为真,则执行 命令表1,
#否则,执行命令表 2
if ... then ... elif ... then ... fi
if 表达式1
then 
	命令表1
elif 表达式2
then
	命令表2
fi
#如果表达式1 为真,则执行 命令表1
#如果表达式2 为真,则执行 命令表2		

多路分支语句

case 变量 in 
    模式1)
        命令表 1  ;;
    模式2 | 模式3)
        命令表 2  ;;
    模式4)
        命令表 3  ;;
    *)
        命令表 4  ;;
esac
#case 多路分支语句只能判断字符串

循环语句

for 变量名 in 单词表
do
    命令表
done
    eg:
        for i in 1 2 3 4 5 6 7 8 9 10   //常用单词表格式
        do
            ....
        done

        for i in {1..10}	//单词表新式用法,指定一个范围
        do 
            ...
        done
#注意:
#变量 每取单词表中的一个单词,循环进行一次,
#单词表中的单词个数,决定循环的额次数	
while 表达式1
do
	命令表 1
done

#注意:
#如果表达式为真则进入循环,执行命令表1
#如果表达式为假则退出循环
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值