shell入门


shell入门

  • 查看当前使用的shell版本
echo $SHELL
hello world

先新建一个helloworld.sh文件,在里面添加以下内容

#!/bin/bash
# 上面指明了脚本解释器,如果使用bash执行该脚本,那么这一行就是一条注释,但是如果通过 ./<文件名> 执行,该行就是一个解释器的声明
# 即便是不写解释器声明,centos默认也是使用bash
echo "hello world"

然后返回,执行

[alasky@localhost ~]$ bash helloworld.sh

注意 此时不可以使用./<文件名>执行sh文件,会提示权限不够,但是使用root也不能执行,因为没有x权限,所以要加上x权限

原因 使用bash可以执行,是因为我们对 /bin/bash 有执行权力,而bash对 .sh 文件有执行权力,所有我们通过bash就可以执行 .sh 文件,但是如果我们直接执行了 .sh 文件,就会因为没有 x 权限而失败

[alasky@localhost ~]$ chmod +x helloworld.sh

然后就可以使用 ./helloworld.sh执行了

[alasky@localhost ~]$ ./helloworld.sh


常用系统变量

$HOME, $PWD, $SHELL, $USER

  • 查看当前系统中所有的变量
set
  • 撤销(删除)变量
unset <变量名>
  • $HOME 表示当前用户的家目录
echo $HOME	#输出	/home/<用户目录名>
  • $PWD 表示当前目录
echo $PWD	#输出	当前目录的绝对路径
  • $SHELL 表示当前使用的shell版本
echo $SHELL	#输出	/bin/bash
  • $USERUSER 表示当前用户名称
echo $USER	#输出	<用户名>


自定义变量的声明

注意

1. shell里面只有字符串类型,所以不用声明变量类型,直接用就可以

2. 定义变量时 = 两边不要加空格,如果变量的值有空格,需要将变量使用引号引起来

3. 定义的变量作用范围只是当前的shell,如果新打开一个shell,那么自定义的变量就没有了

定义普通变量
[alasky@localhost ~]$ a=5	#这一行就相当于声明了一个变量
[alasky@localhost ~]$ b=5
[alasky@localhost ~]$ echo $a+$b	#打印变量,输出 5+5
定义只读变量

使用readonly定义的变量不能修改,也不能删除

[alasky@localhost ~]$ readonly i=10
[alasky@localhost ~]$ i=11	#会报错
  • 把当前shell的变量提升为全局变量,即在其他的shell中也能使用
export <变量名>


特殊变量
  • $n

n为数字,$0代表该脚本名称,$1- 9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 , 十 以 上 的 参 数 需 要 用 大 括 号 包 含 , 如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9,,,{10}

举例 先创建一个sh文件

[alasky@localhost ~]$ vim test1.sh

然后在里面输入

#!/bin/bash
echo "$0  $1   $2"

保存退出后,执行命令

[alasky@localhost ~]$ chmod +x test.sh
[alasky@localhost ~]$ ./test.sh 1 2 3	#输出	1 2 3
  • $#

获取所有输入参数个数,常用于循环

****再创建一个test2.sh.在里面加入

#!/bin/bash
echo $#

保存退出,添加x权限后,执行脚本

[alasky@localhost ~]$ ./test2.sh 1 2 3 4	#输出 4
  • $* 和 $@

KaTeX parse error: Undefined control sequence: \* at position 1: \̲*̲ 这个变量代表命令行中所有的参…*把所有的参数看成一个整体

@ 这 个 变 量 也 代 表 命 令 行 中 所 有 的 参 数 , 不 过 @ 这个变量也代表命令行中所有的参数,不过 @,@把每个参数区分对待

[alasky@localhost ~]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#
echo $*
echo $@

[[alasky@localhost ~]$ bash parameter.sh 1 2 3
parameter.sh  1   2
3
1 2 3
1 2 3
  • $?

最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确

[alasky@localhost ~]$ ./helloworld.sh 
hello world
[alasky@localhost ~]$ echo $?
0


运算
  • 如果想要对定义的变量进行运算,就使用运算式
[alasky@localhost ~]$ a=5
[alasky@localhost ~]$ b=5
[alasky@localhost ~]$ echo $[$a+$b]	#结果是10
  • 也可以使用expr定义,但是使用expr时,每个参数必须用空格隔开
[alasky@localhost ~]$ a=5
[alasky@localhost ~]$ b=5
[alasky@localhost ~]$ expr $a + $b	#结果输出10


条件判断

语法

[ <判断式> ] #注意判断式两边要有空格,判断式中判断符号的两边也要有空格

返回结果 条件非空即为true,[ <字符串> ]也返回true;条件为空,即[] 返回false

  • 两个变量之间比较

    • = 字符串比较
    [alasky@localhost ~]$ a=5
    [alasky@localhost ~]$ b=5
    [alasky@localhost ~]$ [ $a = $b ] #注意
    [alasky@localhost ~]$ echo $?
    
    • -lt 小于(less than)
    [alasky@localhost ~]$ [ 2 -ge 1 ]
    [alasky@localhost ~]$ echo $?
    0
    

    下面就不一一举例了

    • -le 小于等于(less equal)
      -eq 等于(equal)
    • -gt 大于(greater than)
      -ge 大于等于(greater equal)
    • -ne 不等于(Not equal)
  • 文件权限的判断

    • -r 有读的权限(read)
    [alasky@localhost ~]$ [ -w helloworld.sh ]
    [alasky@localhost ~]$ echo $?
    0
    
    • -w 有写的权限(write)
    • -x 有执行的权限(execute)
  • 判断文件类型

    • -e 文件存在(existence)
    [alasky@localhost ~]$ [ -e /home/alasky/helloworld.txt ]
    [alasky@localhost ~]$ echo $?
    1
    
    • -f 文件存在并且是一个常规的文件(file)

    • -d 文件存在并是一个目录(directory)



流程控制

if

语法

if [ 条件判断式 ]
	then 
  		程序 
fi 

或者

if [ 条件判断式 ] 
  	then 
    	程序 
elif [ 条件判断式 ]
	then
		程序
else
	程序
fi

注意

1. [ 条件判断式 ],中括号和条件判断式之间必须有空格

2. if后要有空格

举例 新建一个iftest.sh文件,写一个简单的例子:判断输入的第一个参数的值

[alasky@localhost ~]$ vim iftest.sh
#!/bin/bash
if [ $1 = 1 ]
	then
		echo "这是1"
elif [ $1 = 2 ]
	then
		echo "这是2"
else
	echo "我不知道这是啥"
fi

保存退出后,给新建的脚本添加权限

[alasky@localhost ~]$ chmod +x iftest.sh

测试

[alasky@localhost ~]$ ./iftest 1
这是1
[alasky@localhost ~]$ ./iftest 2
这是2
[alasky@localhost ~]$ ./iftest 3
我不知道这是啥

case

语法

case $变量名 in
	"值1")
    	如果变量的值等于值1,则执行程序1 
    	;;
  	"值2")
    	如果变量的值等于值2,则执行程序2 
    	;;  
  	*)
    	如果变量的值都不是以上的值,则执行此程序 
    	;; 
esac

注意

1. case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束

2. 双分号“;;”表示命令序列结束,相当于java中的break

3. 最后的“*)”表示默认模式,相当于java中的default

举例 使用case判断输入的第一个参数

[alasky@localhost ~]$ vim casetest.sh
#!/bin/bash
case $1 in
	1)
		echo "这是1"
		;;
	2)
		echo "这是2"
		;;
	*)
		echo "我不知道这是啥"
		;;
esac

测试省略


for

语法

for (( 初始值;循环控制条件;变量变化 )) 
	do 
    	程序 
	done

或者

for 变量 in 值1 值2 值3… 
	do 
		程序
	done

举例 打印1到99

[alasky@localhost ~]$ vim fortest.sh
#!/bin/bash
for (( i=0;i<100;i++ ))
	do
		echo $i
	done

while

语法

while [ 条件判断式 ] 
	do 
		程序
	done

举例 打印1到99

[alasky@localhost ~]$ vim whiletest.sh
#!/bin/bash
i=1
while [ $i -le 100 ]
do
	echo $i
	i=[ $i+1 ]
done
[alasky@localhost ~]$ [ -e /home/alasky/helloworld.txt ]
[alasky@localhost ~]$ echo $?
1
[alasky@localhost ~]$ [ -e /home/alasky/helloworld.txt ]
[alasky@localhost ~]$ echo $?
1


读取控制台输入(read)

语法

read [选项] [参数]

选项

​ -p <提示语> 指定读取值时的提示语

​ -t 指定读取时等待的时间(秒)

参数

​ 指定读取的变量名

举例 写一个shell脚本,让用户在控制台输入一个姓名,并返回“姓名+你好”

[alasky@localhost ~]$ vim readtest.sh
#!/bin/bash
read -p "请输入姓名" name
echo $name"你好"
[alasky@localhost ~]$ chmod +x readtest.sh
[alasky@localhost ~]$ ./readtest.sh
请输入姓名alasky
alasky你好


函数
系统函数举例
  • basename

basename命令会删除文件路径的所有前缀,只输出文件名,如果指定了后缀,还会将后缀删除

语法:

basename <文件路径> [后缀名]

举例

[alasky@localhost ~]$ basename /home/alasky/readtest.sh
readtest.sh
[alasky@localhost ~]$ basename /home/alasky/readtest.sh .sh
readtest
  • dirname

从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

语法:

dirname <文件路径>

举例

[alasky@localhost ~]$ dirname /home/alasky/helloworld.sh
/home/alasky


自定义函数

语法

[ function ] funname[()]
{
	Action;
	[return int;]
}
funname

注意

1. 调用函数的语句必须写在函数声明之前,因为shell是解释性语言,从上到下执行,如果在函数声明之前调用函数,会报错

2. 声明函数的关键字function和函数的参数列表()可以省略,但是只能省略一个,不能同时省略

_3. 函数可以定义返回值,但是函数的返回值返回的不是数值,而是函数的执行状态(是否执行成功),_函数返回值,只能通过$?系统变量获得,可以显示加return返回,如果不加,将以最后一条命令运行结果,作为返回值;return后跟数值n(0-255)

举例 定义一个函数,计算两个输入参数的和,并执行该函数

[alasky@localhost ~]$ vim funtest.sh
#!/bin/bash
function sum()
{
    s=0
    s=$[ $1 + $2 ]
    echo "$s"
}

read -p "输入第一个数: " n1;
read -p "输入第二个数: " n2;
sum $n1 $n2;
[alasky@localhost ~]$ chmod +x funtest.sh
输入第一个数: 1
输入第二个数: 2
3


常用的Shell工具

注意 以下举例的常用命令,都是可以直接写在sh脚本文件里的,方便起见,这里就直接写在命令行模式下了


cut

管道工具,用来剪切部分数据

语法

cut [选项] [文件名]

选项

​ -f 列号,提取第即列

​ -d 分割符,按照指定分隔符分割

​ -c 指定具体的字符

举例1 首先创建一个文件作为剪切的文件,分别剪切第1列和第2,3列

[alasky@localhost ~]$ vim cuttest.txt
one1 one2 one3
two1 two2 two3
three1 three2 two3
four1 four2 two3

使用cut提取文件的第一列

[alasky@localhost ~]$ cut -d " " -f 1 cuttest.txt
one1
two1
three1
four1

使用cut提取文件的第二列和第三列

[alasky@localhost ~]$ cut -d " " -f 2,3 cuttest.txt
one2 one3
two2 two3
three2 two3
four2 two3

举例2 提取出ip addr命令打印出来的ip地址(提取ip信息的指令因linux系统而异,出不来结果不要着急,自己摸索一下就好)

[alasky@localhost ~]$ ifconfig eth0 | grep "inet addr" | cut -d: -f 2 | cut -d" " -f 1
192.168.0.105

sed

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出

语法

sed [选项][命令]<文件名>

注意 sed命令只是在缓冲区修改文本内容,实际的文件内容并没有改变!

选项

​ -e 直接在指令列模式上进行sed的动作编辑

​ -i 直接编辑文件

命令

​ na <添加的内容> 追加,n表示第几行,a表示在n的下一行插入添加的内容

​ d 删除

​ s 查找并替换

举例1 将”three1 three2 three3”插入到第2行后面并打印

创建一个新的文件

[alasky@localhost ~]$ vim sedtest.txt
one1 one2 one3
two1 two2 two3
four1 four2 four3

执行命令

[alasky@localhost ~]$ sed '2a three1 three2 three3' sedtest.txt
one1 one2 one3
two1 two2 two3
three1 three2 three3
four1 four2 four3

注意 ! 虽然打印出来是添加了three那一行,但是实际上文件并没有改变

[alasky@localhost ~]$ cat sedtest.txt
one1 one2 one3
two1 two2 two3
four1 four2 four3

举例2 删除刚刚创建的sedtest.txt下包含four的行

[alasky@localhost ~]$ sed '/four/d' sedtest.txt
one1 one2 one3
two1 two2 two3

注意 这个文件仍旧没有改变

举例3 替换第三行为”three1 three2 three3”

[alasky@localhost ~]$ sed 's/four/three/g' sedtest.txt
one1 one2 one3
two1 two2 two3
three1 three2 three3

awk

把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理

语法

awk [选项] '内容1{操作1} 内容2{操作2}...内容n{操作n}' <文件名>

选项

​ -F 指定输入文件的分隔符

​ -v 赋值一个用户定义变量

举例 搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割

[alasky@localhost ~]$ sudo cp /etc/passwd ./
[alasky@localhost ~]$ awk -F : '/^root/{print $1","$7}' passwd 
root,/bin/bash

sort

将文件进行排序,并将排序结果标准输出

语法

sort [选项] <文件名>

选项
-n 依照数值的大小排序

​ -r 逆序

​ -t 设置排序时所用的分隔符

​ -k 指定需要排序的列

举例 创建一个文件,按照文件内容的第二列逆序排序

[alasky@localhost ~]$ vim sorttest.txt
小明:1:18:1199834
小红:2:34:8970389
小刚:3:21:3123478
[alasky@localhost ~]$ sort -t : -nrk 2 sorttest.txt
小刚:3:21:3123478
小红:2:34:8970389
小明:1:18:1199834

o1 two2 two3
three1 three2 three3




 ##### awk

把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理

**语法**

```bash
awk [选项] '内容1{操作1} 内容2{操作2}...内容n{操作n}' <文件名>

选项

​ -F 指定输入文件的分隔符

​ -v 赋值一个用户定义变量

举例 搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割

[alasky@localhost ~]$ sudo cp /etc/passwd ./
[alasky@localhost ~]$ awk -F : '/^root/{print $1","$7}' passwd 
root,/bin/bash
sort

将文件进行排序,并将排序结果标准输出

语法

sort [选项] <文件名>

选项
-n 依照数值的大小排序

​ -r 逆序

​ -t 设置排序时所用的分隔符

​ -k 指定需要排序的列

举例 创建一个文件,按照文件内容的第二列逆序排序

[alasky@localhost ~]$ vim sorttest.txt
小明:1:18:1199834
小红:2:34:8970389
小刚:3:21:3123478
[alasky@localhost ~]$ sort -t : -nrk 2 sorttest.txt
小刚:3:21:3123478
小红:2:34:8970389
小明:1:18:1199834
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值