Shell基础

什么是shell

shell是linux的命令解释器
它向用户提供了一个向linux内核发送请求以便运行程序
shell处在内核与外层应用程序之间
在用户与系统之间进行交互的作用
与windows的鼠标点击软件后
就能运行软件的功能类似
如windows下创建一个文件夹
我们先决定去哪里新建即进入该路径
再右键选择新建文件夹即可
在linux当中也是通过类似的方法
不过完全使用命令行罢了
这就是shell
能够在用户与系统间进行交互实现相应的功能
在这里插入图片描述
shell是一个强大的编程语言
与一般的编程语言不同的是
它可以直接使用系统命令
这可以大大的减小linux管理员的工作量
只需会写shell脚本即可自动化管理linux

shell的类型

hell有很多的类型
现在一般是使用bash

cat /etc/shells

可以查看当前linux支持的shell类型

系统默认的Shell解析器bash

echo $SHELL

简单例子

第一行#!/bin/bash
标称以下写的脚本使用的是bash
像c语言的 #include<stdio.h> 一样
除了第一行的#!/bin/bash
其他以#开头的都是注释
其他即为程序的主体
可以调用系统命令

#表示注释

创建第一个Shell脚本

touch HelloWorld.sh
vim HelloWorld.sh

写入

#!/bin/bash

echo "Hello World!"

执行脚本

[root@localhost yuan]# ll
总用量 32
-rw-r--r--. 1 root root    15 12月 20 15:55 1.txt
-rw-r--r--. 1 root root    22 12月 20 15:55 2.txt
-rw-r--r--. 1 root root    33 12月 20 22:59 HelloWorld.sh
-rw-r--r--. 1 root root  3573 12月 20 16:30 ShellCode.cpp
-rw-r--r--. 1 root root 10240 12月 20 22:27 test.tar
-rw-r--r--. 1 root root   154 12月 20 16:29 ???乥??.txt
[root@localhost yuan]# sh HelloWorld.sh 
Hello World!
[root@localhost yuan]# bash HelloWorld.sh 
Hello World!
[root@localhost yuan]# ./HelloWorld.sh
-bash: ./HelloWorld.sh: 权限不够
[root@localhost yuan]# 

bash 文件
sh 文件
都是bash去读取里面的命令然后执行HelloWorld.sh本身不需要执行权限

[root@localhost yuan]# chmod 777 HelloWorld.sh 
[root@localhost yuan]# ./HelloWorld.sh 
Hello World!
[root@localhost yuan]# 

创建文本文件并写入内容

#!/bin/bash

cd /home/yuan
touch test.txt
echo "I love cls" >> test.txt

历史命令

history [选项] [历史命令保存文件]

选项:
​ -c :清空历史命令
​ -w :把缓存中的历史命令写入历史命令保存文件。如果不手工指定历史命令保存文件,则放入默认历史命令保存文件 ~/.bash_history 中
我们使用 history 命令查看历史命令和 ~/.bash_history 文件中保存的历史命令是不同的。那是因为当前登录操作的命令并没有直接写入 ~/.bash_history 文件,而是保存在缓存中。需要等当前用户注销之后,缓存中的命令才会写入 ~/.bash_history 文件。如果我们需要把内存中的命令直接写入 ~/.bash_history 文件,而不等用户注销才写入,可以使用 history -w 命令

输入输出重定向

Bash 的标准输入输出
设备设备文件名文件描述符类型键盘/dev/stdin0标准输入显示器/dev/stdout1标准输出显示器/dev/stderr2标准错误输出
设备设备文件名文件描述符类型键盘/dev/stdin0标准输入显示器/dev/stdout1标准输出显示器/dev/stderr2标准错误输出
输出重定向
在这里插入图片描述
解释下什么叫输出重定向:

命令的输出本身是应该输出给标准输出设备的,也就是输出到显示器上,重定向就是把它的输出方向改变,让它不在输出到显示器上,而是让它输出到文件中,这就是输出重定向。

标准输出重定向:

ll > abc

标准错误输出重定向

lljfkdf 2>abc

多命令顺序执行x

在这里插入图片描述

[root@hepingfly 桌面]# ll;date;cd /home/      这三条命令会按照顺序执行,不管前面命令执行成功还是失败,后面的命令都会照常执行

[root@hepingfly home]# ls && echo yes    如果第一个命令正确执行了,我就输出一个 yes。如果第一个命令报错,第二个命令是不会执行的。

[root@hepingfly home]# lsfaa || echo no    如果第一个命令没有正确执行,我就输出一个 no。如果第一个命令正确执行,第二个命令是不会执行的

[root@hepingfly home]# ll && echo yes || echo no  这条命令的意思是,如果第一个命令正确执行,则输出 yes,否则输出 no

shell 特殊符号

在这里插入图片描述

[root@hepingfly home]# a=$(date)      系统命令的执行结果赋值给变量
[root@hepingfly home]# echo $a
2019年 05月 04日 星期六 21:18:46 CST
[root@hepingfly home]# b=$(ll /home/)      理论上只要命令有输出,就可以赋值给变量
[root@hepingfly home]# echo $b

变量

变量有哪些类型:
用户自定义变量 2.环境变量 3.位置参数变量 4.预定义变量

常用的系统变量

$HOME, $PWD, $SHELL, $USER, $PATH等

[root@localhost yuan]# echo $HOME
/root
[root@localhost yuan]# echo $HOME
/root
[root@localhost yuan]# echo $PWD
/home/yuan
[root@localhost yuan]# echo $SHELL
/bin/bash
[root@localhost yuan]# echo $USER
root
自定义变量

语法
变量 = 值
中间不要加空格

[root@localhost yuan]# A=1
[root@localhost yuan]# echo $A
1

撤销变量
unset 变量

[root@localhost yuan]# unset A
[root@localhost yuan]# echo $A

声明静态变量
readonly变量,注意:不能unset

readonly B=3

变量命名规则

  1. 变量名称可以由字母、数字、下划线组成,但是不能以数字开头
  2. 在 Bash 中,变量的默认类型都是字符串型,如果要进行数值运算,则必须指定变量类型为数值型
  3. 变量用等号连接值,等号左右两侧不能有空格,比如你在 shell 中定义一个变量,可以这么写: name=shp 但是不能这么写: name = shp 这种写法是错误的 因为在 linux 中命令的格式是: 命令 空格 选项 空格 参数 你定义变量的时候加空格,它会把你的变量当成 linux 命令去解析,这样显然有问题
  4. 变量的值如果有空格,需要使用单引号或者双引号扩起来。
  5. 如果是要把命令的结果作为变量值赋予变量,则需要使用反引号或者 $() 把命令包起来
    [root@hepingfly home]# test=$(date) 把 date 命令的执行结果赋值给变量
    [root@hepingfly home]# echo $test
    2019年 05月 05日 星期日 21:14:28 CST
  6. 环境变量名建议大写,用于区分
环境变量

可以把变量提升为全局变量,可供其他Shell程序使用
export 变量名

export 变量名=变量值
特殊变量 $n

在这里插入图片描述

count.sh 脚本:
#!/bin/bash
a=$1   # 这里拿到命令行中第一个参数
b=$2   # 这里拿到命令行中的第二个参数
sum=$(($a+$b))     # 在 shell 当中如果想要进行数值运算,需要使用 $(()) 把你要运算的算式给括起来,它才知道这是数值运算, $() 是用来括系统命令的,你括起来之后它才知道这是系统命令,然后执行,把结果赋值给变量
echo $sum
echo $0     # 这个就是输出命令行本身

#结果
[root@hepingfly hepingfly]# ./count.sh 22 11
33
./count.sh
param.sh 脚本:
#!/bin/bash
for i in "$*"     # $* 是把所有参数当成一个整体
        do
                echo $i    # 这里我有多少个参数,就会一把输出出来

        done
echo "============"
for y in "$@"        #  $@ 是把参数区别对待
        do
                echo $y   # 有多少个参数,循环多少次,依次输出出来

        done

echo "============"
echo "$#"       # 这里会输出所有参数的个数

结果

[root@localhost yuan]# ./param.sh 1 2 3 4 5
1 2 3 4 5
===========
1
2
3
4
5
===========
5

预定义变量

在这里插入图片描述

[root@hepingfly 桌面]# fdfda           随便乱输入一个命令
bash: fdfda: command not found
[root@hepingfly 桌面]# echo $?       输出最后一次命令执行状态
127									# 非 0 表示命令未正确执行
[root@hepingfly 桌面]# ll
总用量 28
-rw-r--r--. 1 root root 25872 3月  28 22:28 mysql80-community-release-el6-2.noarch.rpm
[root@hepingfly 桌面]# echo $?
0   
PATH 变量

系统查找命令的路径

[root@hepingfly bin]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin

PATH 变量的值是用 『:』分割的路径,这些路径就是系统查找命令的路径。也就是说当我们输入一个程序名,如果没有写入路径,系统就会到 PATH 变量定义的路径去找是否有可以执行的程序。如果找到则执行,否则会报 “命令没有发现的错误”。

现在假如说我们有一个自己的脚本,我不想输入路径就直接运行,有什么方法?

方法一:

把你自己写的脚本放到环境变量的路径下,这样就可以直接执行了。例如,把脚本放到 /bin 目录下

方法二:

利用变量叠加去修改环境变量的值

PATH="$PATH":/home/hepingfly/
declare 声明变量类型

linux 中所有变量的默认类型都是字符串类型,我们需要把变量声明为整数类型才可以进行运算。使用 declare 命令就可以实现声明变量的类型。

declare [+/-] [选项] 变量名

选项:
​ - :给变量设定类型属性
​ + :取消变量的类型属性
​ -a :将变量设定为数组类型
​ -i :将变量声明为整数类型
​ -r :将变量声明为只读变量。注意:一旦设定为只读变量,既不能修改变量的值,也不能删除变量,设置不能通过 +r 取消只读属性。
​ -x :将变量声明为环境变量
​ -p :显示指定变量的被声明的类型

变量设定为整数类型:

[root@hepingfly hepingfly]# a=1
[root@hepingfly hepingfly]# b=2
[root@hepingfly hepingfly]# c=$a+$b          直接相加是两个字符串做拼接操作
[root@hepingfly hepingfly]# echo $c
1+2
[root@hepingfly hepingfly]# declare -i c=$a+$b        声明变量 c 为数值类型
[root@hepingfly hepingfly]# echo $c
3

数值运算

在 shell 中你如果要进行数值运算,推荐使用 ( ( 运 算 式 ) ) 方 式 运 算 或 者 ((运算式)) 方式运算 或者 (())[运算式]
或者expr命令
expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串
计算字串长度

expr length “this is a test”
 > expr 14 % 9
 5
 > expr 10 + 10
 20
 > expr 1000 + 900
 1900
 > expr 30 / 3 / 2
 5
 > expr 30 \* 3 (使用乘号时,必须用反斜线屏蔽其特定含义。因为shell可能会误解显示星号的意义)
 90
 > expr 30 * 3
 expr: Syntax error

$((运算式))

[root@localhost yuan]# c=$((1+2))
[root@localhost yuan]# echo $c
3

关系运算符

流程控制

if 判断

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

# 或者(推荐)
if [ 条件判断式 ]
then
    程序
elif [ 条件判断式 ]
then
    程序
fi

实例

#!/bin/bash
if [ $1 -ge 60 ]
then
    echo 及格
elif [ $1 -lt 60 ]
then
    echo "不及格" 
fi

case 分支

case $变量名 in
"值1")
如果变量值等于值1,则执行此处程序1
;;
"值2")
如果变量值等于值2,则执行此处程序2
;;
...省略其它分支...
*)
如果变量值不等于以上列出的值,则执行此处程序
;;
esac

实例
当命令行参数为1时输出“周一”,2时输出“周二”,其他情况输出“其它”

case $1 in
"1")
echo 周一
;;
"2")
echo 周二
;;
*)
echo 其它
;;
esac

for 循环

# 语法1
for 变量名 in 值1 值2 值3...
do
    程序
done

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

实例
输出从1加到100的值。

#!/bin/bash 
SUM=0  
for ((i=1;i<=100;i++)) 
do     
    SUM=$[$SUM+$i] 
done 

echo $SUM

while 循环

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

实例
输出从1加到100的值。

#!/bin/bash
SUM=0
i=0

while [ $i -le $1 ]
do
    SUM=$[$SUM+$i]
    i=$[$i+1]
done       
echo $SUM

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。关系运算符判断两个数字之间的大小,并返回true(1)或者false(0)。True和false可以参与后面的布尔运算。

#!/bin/sh

a=10
b=20
if [ $a -eq $b ]
then
   echo "$a -eq $b : a is equal to b"
else
   echo "$a -eq $b: a is not equal to b"
fi

if [ $a -ne $b ]
then
   echo "$a -ne $b: a is not equal to b"
else
   echo "$a -ne $b : a is equal to b"
fi

if [ $a -gt $b ]
then
   echo "$a -gt $b: a is greater than b"
else
   echo "$a -gt $b: a is not greater than b"
fi

if [ $a -lt $b ]
then
   echo "$a -lt $b: a is less than b"
else
   echo "$a -lt $b: a is not less than b"
fi

if [ $a -ge $b ]
then
   echo "$a -ge $b: a is greater or  equal to b"
else
   echo "$a -ge $b: a is not greater or equal to b"
fi

if [ $a -le $b ]
then
   echo "$a -le $b: a is less or  equal to b"
else
   echo "$a -le $b: a is not less or equal to b"
fi

在这里插入图片描述

布尔运算符

在 Bash 里有这样的常量,即 true 和 false,表示真,表示假。对它们可以进行与、或、非运算等常规的逻辑运算。
在这里插入图片描述

#!/bin/sh

a=10
b=20

if [ $a != $b ]
then
   echo "$a != $b : a is not equal to b"
else
   echo "$a != $b: a is equal to b"
fi

if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a -lt 100 -a $b -gt 15 : returns true"
else
   echo "$a -lt 100 -a $b -gt 15 : returns false"
fi

if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a -lt 100 -o $b -gt 100 : returns true"
else
   echo "$a -lt 100 -o $b -gt 100 : returns false"
fi

if [ $a -lt 5 -o $b -gt 100 ]
then
   echo "$a -lt 100 -o $b -gt 100 : returns true"
else
   echo "$a -lt 100 -o $b -gt 100 : returns false"
fi

字符串运算符

字符有可能是数字、字母、空格、其他特殊字符,而字符串有可能是它们中的一种或者多种的组合。
在这里插入图片描述

#!/bin/bash

a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a is equal to b"
else
   echo "$a = $b: a is not equal to b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a is not equal to b"
else
   echo "$a != $b: a is equal to b"
fi
if [ -z $a ]
then
   echo "-z $a : length is 0"
else
   echo "-z $a : length is not 0"
fi

if [ -n "$a" ]
then
   echo "-n $a : length is not 0"
else
   echo "-n $a : length is 0"
fi
if [ $a ]
then
   echo "$a : string is not null"
else
   echo "$a : string is null"
fi

文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

例如,变量 file 表示文件“~/test.sh”,它的大小为100字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性


if [ -x $file ]
then
   echo "File has execute permission"
else
   echo "File does not have execute permission"
fi

if [ -f $file ]
then
   echo "File is an ordinary file"
else
   echo "This is sepcial file"
fi

if [ -d $file ]
then
   echo "File is a directory"
else
   echo "This is not a directory"
fi

if [ -s $file ]
then
   echo "File size is zero"
else
   echo "File size is not zero"
fi

if [ -e $file ]
then
   echo "File exists"
else
   echo "File does not exist"
fi

在这里插入图片描述

字符串操作

获取字符串长度

string="abcd"
echo ${#string} #输出 4

提取子字符串

string="alibaba is a great company"
echo ${string:1:4} #输出liba

查找子字符串

string="alibaba is a great company"
echo `expr index "$string" is`

数组

定义数组
array_name=(value1 … valuen)
例如

array_name=(value0 value1 value2 value3)
#或者
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

访问元素
${array_name[index]}

#!/bin/sh

NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"

获取数组的长度

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

函数

自定义函数
[ function ] funname[()]
{
    Action;
    [return int;]
}

# 调用
funname 参数1 参数2...

实例
实例
计算输入两个参数的和

#!/bin/bash

function getSum(){
    SUM=$[$n1+$n2]
    echo "sum=$SUM"
}   

read -p "请输入第一个参数n1:" n1
read -p "请输入第二个参数n2:" n2

# 调用 getSum 函数
getSum $n1 $n2

实用参考Demo

判断运行脚本时是否输入了指定个数的参数
#!/bin/sh

if [ $# != 2 ];then
    #参数不等于2个时提示 参数不正确
    echo "Parameter incorect."
    exit 1
fi

自己设置环境变量
#!/bin/bash

#执行/etc/profile这个文件里的shell指令
source /etc/profile
#重新定义全局变量PATH
export PATH="/usr/local/bin:/usr/bin"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值