【shell】shell是什么,shell脚本又是什么?

1. shell是什么?

1.1 shell简介

  • shell英文翻译为壳,外壳的意思
  • IT界,Shell 是指一种应用程序,用于访问操作系统内核的服务,是用户和系统内核的桥梁
    Shell 既是一种命令语言,又是一种程序设计语言 ,Shell 是一个用 C 语言编写的程序
    在这里插入图片描述

2.1 shell的种类

通过cat /etc/shells 或者 chsh -l查看当前linux支持的shell

[root@localhost ~]$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

shell的名称:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
……
最常见的是Bash,也就是 Bourne Again Shell,易用和免费。同时,Bash 也是大多数Linux 系统默认的 Shell。

  • shell种类千千万,有个极品shell,等你玩转linux,一定要试试,那就是zsh,不但美观,功能强大,而且支持回显,自动补齐,高亮显,各种主题等你来配置,就是配置有点麻烦,想试试的去找度娘,贴图:
    在这里插入图片描述

2. shell的使用

2.1 bash shell特点

  1. 命令和文件自动补齐:敲出一半直接tab键补齐,如果能补齐的有很多,连续两下tab都能显示出来,所以敲到本目录的唯一性时再tab事半功倍!
  2. 命令历史记录功能:上下键(搜索前一个后一个使用过的命令)!!(执行上一条命令)、^r(ctrl+r,可以用关键字符搜索使用过的命令,回车直接执行),
  3. 快捷键:在命令行输入命令时使用
快捷键作用
ctrl+d删除选中字符
ctrl+a跳到最前面
ctrl+e跳到最后面
ctrl+u从后往前删除全部
ctrl+k从前往后删除全部
ctrl+l清屏
ctrl+c结束当前作业(包括敲一半的命令)
ctrl+z当前程序后台运行,与命令后面加&一样的作用(sleep 10& )
jobs查看后台运行的程序
fg 2回到某个正在后台运行的程序
bg 2让后台的某个程序继续运行
  1. 输入输出重定向
命令结果
cmd > file将命令输出的结果放到某个文件中,覆盖
cmd >> file…追加
cat > file <<EOF 你好 EOF将“你好”放到file中,第一个EOF后面要回车,在你好后面回车,EOF回车
  1. 命令排序
命令解释
;前面的命令执行完就执行后面的
&&前面命令执行成功了才执行后面的
管道符管道符前面命令失败才执行后面的

管道符就是 |

  1. shell通配符(元字符) 表示的不是本意
字符含义
*匹配任意多个字符 ls in* rm -rf * rm -rf *.pdf
?匹配任意一个字符 touch love loove live; ll l?ve
[ ]匹配括号中任意一个字符 [abc] [a-z] [0-9] [a-zA-Z0-9] ll l[io]ve
{ }集合 touch file{1…9}
\转义符,让元字符回归本意
\t相当于tab,两个字符之间有距离
\n换行

2.2 shell变量

什么时变量,说白了,就是用一个字符串,代表某些特定内容的特殊字符串,可以给变量赋值,然后再调用他,怎么调用呢,前面加个$符,如下:

[root@localhost ~]$ echo $HOSTNAME
localhost.localdomain

2.2.1 环境变量

系统级环境变量

linux操作系统启动过程,会加载全局配置文件,让全局配置文件中的定义的变量伴随着开机就生效,共享给所有用户所有Shell程序使用。
全局配置文件
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc

用户级环境变量

系统启动后某个用户登录进来,会加载个人配置文件,让个人配置文件中定义的变量伴随登录就生效,共享给当前用户的Shell程序使用。
个人配置文件
当前用户/.bash_profile
当前用户/.bashrc

当然,由于以上的文件时开机或者登录就直接被加载的,你可以写个脚本,放到这里面,让其开机或者登录就直接执行。

查看环境变量的方法
查看Shell变量(系统环境变量+自定义变量+函数)

set

查看当前Shell系统环境变量

env
常见的环境变量
变量内容
PATH与windows环境变量PATH功能一样,设置命令的搜索路径,以冒号为分割
HOME当前用户主目录:/root
SHELL当前shell解析器类型:/bin/bash
HISTFILE显示当前用户执行命令的历史列表文件:/root/.bash_history
PWD显示当前所在路径:/root
OLDPWD显示之前的路径
HOSTNAME显示当前主机名:itheima
HOSTTYPE显示主机的架构,是i386、i686、还是x86、x64等:x86_64
LANG设置当前系统语言环境:zh_CN.UTF-8
PS1当前shell提示符
预定义变量
变量内容
$0脚本名
$*所有的参数
$@所有的参数
$#参数的个数
$$当前进程的PID
$!上一个进程的PID
$?上一个命令的返回值
$n位置变量,传入脚本的变量值,第一个为$1,第二个为$2,以此类推。

看一下实例

[root@localhost ~]$ cat test.sh
#!/bin/bash
echo "第2个位置参数是$2"
echo "第1个位置参数是$1"
echo "第4个位置参数是$4"

echo "所有参数是: $*"
echo "所有参数是: $@"
echo "参数的个数是: $#"
echo "当前进程的PID是: $$"

echo \$1=$1
echo \$2=$2
echo \$3=$3
echo \$*=$*
echo \$@=$@
echo \$#=$#
echo \$$=$$
echo \$?=$?
[root@localhost ~]$ bash test.sh ni hao hello world
第2个位置参数是hao
第1个位置参数是ni
第4个位置参数是world
所有参数是: ni hao hello world
所有参数是: ni hao hello world
参数的个数是: 4
当前进程的PID是: 2568
$1=ni
$2=hao
$3=hello
$*=ni hao hello world
$@=ni hao hello world
$#=4
$$=2568
$?=0
标准错误和标准输出

Linux默认定义两个变量:1和2;

1 表示标准输出
2 表示错误输出

通常用于重定向输出日志,
其中2 > &1的&符号表示错误输出重定向到标准输出,如下,标准错误和标准输入都重定向到info.log

 nohup cmd 1 > info.log 2>&1 &

nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。

nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。

& 是指后台运行;

注意:nohup 的功能和& 之间的功能并不相同。其中,nohup 可以使得命令永远运行下去和用户终端没有关系。当我们断开ssh 连接的时候不会影响他的运行。而& 表示后台运行。当ssh 断开连接的时候(用户退出或挂起的时候),命令也自动退出。

当然我们可以把两者结合起来使用,来实现命令的后台运行并且和用户终端没有关系。

nohup command & 

2.2.2 自定义变量

先介绍一下父子Shell环境:
直接在命令行敲 bash,你表面看没有任何变化,但是着已经进入当前shell的子shell中了 再敲exit,退出子shell

[root@localhost ~]$ bash
[root@localhost ~]$ exit
exit
[root@localhost ~]$

如果再脚本中体现,有2个Shell脚本文件 A.sh 和 B.sh
如果 在A.sh脚本文件中执行了B.sh脚本文件, 那么A.sh就是父Shell环境, B.sh就是子Shell环境

局部变量

就是定义在一个脚本文件或者当前shell(不包含子shell)中的变量, 只能在这个脚本文件或者当前shell中使用的变量
变量定义的方法

[root@localhost ~]$ wenhou=hello
[root@localhost ~]$ echo $wenhou
hello
变量定义规则
1. 变量名称可以有字母,数字和下划线组成, 但是不能以数字开头
2. 等号两侧不能有空格
3. 在bash环境中, 变量的默认类型都是字符串类型, 无法直接进行数值运算
4. 变量的值如果有空格, 必须使用双引号括起来
5. 不能使用Shell的关键字作为变量名称
全局变量

就是在当前脚本文件中定义全局变量, 这个全局变量可以在当前Shell环境与子Shell环境中都可以使用
变量定义的方法

[root@localhost ~]$ export ni=wo
[root@localhost ~]$ bash
[root@localhost ~]$ echo $ni
wo
[root@localhost ~]$ exit
exit
脚本执行过程中输入变量

在执行过程需要获取随时输入的变量,则可以按照下面的格式:
read -p 提示信息 变量

[root@localhost ~]$ cat read.sh
#!/bin/bash
read -p "请输入你的名字:" name
echo $name
[root@localhost ~]$ bash read.sh
请输入你的名字:root
root

2.3.shell常用的命令

以后再写

3. shell脚本

个人理解,shell脚本就是将各种命令集合起来,利用各种变量,函数,流程控制,判断语句,形成自动化或者半自动化的小程序。

我们将这些东西放到一个文件中,然后执行它,这个文件就叫脚本。

这个文件叫什么都可以,但是为了让别人知道这是shell脚本,约定俗成都起名为xxx.sh

一般sheel脚本编写都会先定义变量,再定义函数,最后用控制流程语句去调用参数和函数,防止脚本很乱,逻辑不清晰!

脚本的第一行一般都会注明使用的是什么环境,比如:

[root@localhost ~]$ cat if.sh
#!/bin/bash
...

执行脚本有很多方法:

  1. #source 01.sh 不需要执行权限 在当前shell中执行
  2. #. ./01.sh 不需要执行权限 在当前shell中执行
  3. #bash 01.sh 不需要执行权限 在子shell中执行(# sh 01.sh)
  4. #./01.sh 需要执行权限 在子shell中执行
  5. #/root/01.sh 需要执行权限 在子shell中执行

注意:最后两种方法执行脚本时,对于管理员来说只需要由x权限,但是对于普通用户来说需要 r 和 x 的权限

3.1 流程控制

流程控制说白了,就是满足什么条件然后干什么

3.1.1 if语句

如果怎么样就干什么,否则就干什么

结构公式:

if 条件测试1;
then
命令序列
elif 条件测试2;
then
命令序列
else
命令序列
fi

其中elif可以有多个,也可以没有,else可以没有,但是不能多有,最多就一个,fi必须有,作为if语句的结束。
例子:

[root@localhost ~]$ cat if.sh
#!/bin/bash
a=1
b=1
if [ $a = $b ];
then
        echo "ok"
elif [ a != b ];
then
        echo "not ok"
else
        echo "qita"
fi
[root@localhost ~]$ bash if.sh
ok

3.1.2 case语句

匹配某个变量,匹配到就干什么

结构公式:

case $变量名 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后命令序列
esac

例子:

[root@localhost ~]$ cat case.sh
#!/bin/bash
case $1 in
hello)
    echo "world"
;;
nihao)
    echo "shijie"
;;
shell)
    echo "bash"
;;
*)
    echo "请从新输入"
esac
[root@localhost ~]$ bash case.sh hello
world
[root@localhost ~]$ bash case.sh nihao
shijie
[root@localhost ~]$ bash case.sh abc
请从新输入

3.1.3 for循环

从某个列表中挨个取出值,然后用这些值干什么

结构公式:

for 变量名 [ in 取值列表 ]
do
循环体
done

示例:

[root@localhost ~]$ cat for.sh
#!/bin/bash
for i in {"a","b","c"}
do
echo $i
done
[root@localhost ~]$ bash for.sh
a
b
c

3.1.4 while语句

当满足什么条件时就干什么

结构公式:

while 条件测试
do
循环体
done

示例:

[root@localhost ~]$ cat while.sh
#!/bin/bash
i=1
while [ $i -le 10 ]
do
        echo $i
        let ++i
        sleep 1
done
[root@localhost ~]$ bash while.sh
1
2
3
4
5
6
7
8
9
10

3.1.5 until语句

当什么条件不满足的时候就干什么事

结构公式:

until 条件测试
do
循环体
done

示例:

[root@localhost ~]$ cat until.sh
#!/bin/bash
i=1
until [ $i -ge 10 ]
do
        echo $i
        let ++i
        sleep 1
done
[root@localhost ~]$ bash until.sh
1
2
3
4
5
6
7
8
9

3.2 条件测试

语法:
格式1: test 条件表达式
格式2: [ 条件表达式 ]
格式3: [[ 条件表达式 ]]
注意: 格式2与3 在写内容的时候,[ ]与表达式之间要有空格,且格式3支持正则表达式,支持&& ||。

3.2.1 文件判断

参数内容
[ -a FILE ]如果 FILE 存在则为真。
[ -b FILE ]如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ]如果 FILE 存在且是一个字特殊文件则为真。
[ -d FILE ]如果 FILE 存在且是一个目录则为真。
[ -e FILE ]如果 FILE 存在则为真。
[ -f FILE ]如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ]如果 FILE 存在且已经设置了SGID则为真。
[ -h FILE ]如果 FILE 存在且是一个符号连接则为真。
[ -k FILE ]如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ]如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ]如果 FILE 存在且是可读的则为真。
[ -s FILE ]如果 FILE 存在且大小不为0则为真。
[ -t FD ]如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ]如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ]如果 FILE 如果 FILE 存在且是可写的则为真。
[ -x FILE ]如果 FILE 存在且是可执行的则为真。
[ -O FILE ]如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ]如果 FILE 存在且属有效用户组则为真。
[ -L FILE ]如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ]如果 FILE 存在 并已经被更改,则为真。
[ -S FILE ]如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ]如果 FILE1 比 FILE2新, 或者 FILE1 存在且FILE2 不存在则为真。
[ FILE1 -ot FILE2 ]如果 FILE1 比 FILE2 老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ]如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。

示例:

[root@localhost ~]$ test -d /etc/passwd
[root@localhost ~]$ echo $?
1
[root@localhost ~]$ test -d /etc/yum.repos.d/
[root@localhost ~]$ echo $?
0
[root@localhost ~]$ [ -d /etc/passwd ] && echo $?
[root@localhost ~]$ [ -d /etc/yum.repos.d ] && echo $?
0

3.2.2 数值判断

参数含义
-gt大于
-lt小于
-eq等于
-ne不等于
-ge大于等于
-le小于等于

示例:

[root@localhost ~]$ [ 2 -gt 1 ]; echo $?
0
[root@localhost ~]$ [ 2 -lt 1 ]; echo $?
1
[root@localhost ~]$ [ 2 -le 1 ]; echo $?
1
[root@localhost ~]$ [ 2 -ne 1 ]; echo $?
0
[root@localhost ~]$ [ 2 -eq 1 ]; echo $?
1
[root@localhost ~]$ [ 2 -ge 1 ]; echo $?
0

3.2.3 字符串判断

参数含义
str1 == str2当两个串有相同内容、长度时为真
str1 != str2当串str1和str2不等时为真
-n str1当串的长度大于0时为真(串非空)
-z str1当串的长度为0时为真(空串)
str1当串str1为非空时为真

示例:

[root@localhost ~]$ [ "aaa" == "aaa" ]; echo $?
0
[root@localhost ~]$ [ "bbb" != "aaa" ]; echo $?
0
[root@localhost ~]$ [ -n "aaa" ]; echo $?
0
[root@localhost ~]$ [ -z "aaa" ]; echo $?
1
[root@localhost ~]$ [ "aaa" ]; echo $?
0

3.2.4 复杂逻辑判断

参数含义
-a
-o
!

示例:

[root@localhost ~]$ [ 1 -lt 2 -a 5 -gt 2 ];echo $?
0
[[root@localhost ~]$ [ 1 -lt 2 -a 5 -gt 10 ];echo $?
1
[root@localhost ~]$ [ 1 -lt 2  -o 5 -gt 10 ];echo $?
0
[root@localhost ~]$ [ "bbb" != "aaa" ]; echo $?
0

3.3 函数

完成特定功能的代码片段(块)
在shell中定义函数可以使代码模块化,便于复用代码
函数必须先定义才可以使用

结构格式:
函数名() {
函数要实现的功能代码
}

示例:

[root@localhost ~]$ cat hanshu.sh
#!/bin/bash
#定义函数
hanshu(){
echo "我是函数"
echo "我是函数的位置参数$1"
}
#调用函数
hanshu hello
[root@localhost ~]$ bash hanshu.sh
我是函数
我是函数的位置参数hello

3.4 影响程序的shell内置命令

命令结果
;if语句,后面要加分号,不然就会报错
true可以加在while语句 while ture,让循环一直进行
false失败,反正我没怎么用过,不知道怎么用
shift使位置参数向左移动,默认移动1位,可以使用shift 2
exit退出整个程序
break结束当前循环,或跳出本层循环
continue忽略本次循环剩余的代码,直接进行下一次循环
select选择性执行

示例:

[root@localhost ~]$ vim break.sh 
#!/bin/bash
for i in {1..10}
do
        if [ $i -eq 5 ]
        then
                break
        fi
        echo $i
done
[root@localhost ~]$ vim continue.sh
#!/bin/bash
for i in {1..10}
do
        if [ $i -eq 5 ]
        then
                continue
        fi
        echo $i
done
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxllstar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值