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特点
- 命令和文件自动补齐:敲出一半直接tab键补齐,如果能补齐的有很多,连续两下tab都能显示出来,所以敲到本目录的唯一性时再tab事半功倍!
- 命令历史记录功能:上下键(搜索前一个后一个使用过的命令)!!(执行上一条命令)、^r(ctrl+r,可以用关键字符搜索使用过的命令,回车直接执行),
- 快捷键:在命令行输入命令时使用
快捷键 | 作用 |
---|---|
ctrl+d | 删除选中字符 |
ctrl+a | 跳到最前面 |
ctrl+e | 跳到最后面 |
ctrl+u | 从后往前删除全部 |
ctrl+k | 从前往后删除全部 |
ctrl+l | 清屏 |
ctrl+c | 结束当前作业(包括敲一半的命令) |
ctrl+z | 当前程序后台运行,与命令后面加&一样的作用(sleep 10& ) |
jobs | 查看后台运行的程序 |
fg 2 | 回到某个正在后台运行的程序 |
bg 2 | 让后台的某个程序继续运行 |
- 输入输出重定向
命令 | 结果 |
---|---|
cmd > file | 将命令输出的结果放到某个文件中,覆盖 |
cmd >> file | …追加 |
cat > file <<EOF 你好 EOF | 将“你好”放到file中,第一个EOF后面要回车,在你好后面回车,EOF回车 |
- 命令排序
命令 | 解释 |
---|---|
; | 前面的命令执行完就执行后面的 |
&& | 前面命令执行成功了才执行后面的 |
管道符管道符 | 前面命令失败才执行后面的 |
管道符就是 |
- 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
...
执行脚本有很多方法:
- #source 01.sh 不需要执行权限 在当前shell中执行
- #. ./01.sh 不需要执行权限 在当前shell中执行
- #bash 01.sh 不需要执行权限 在子shell中执行(# sh 01.sh)
- #./01.sh 需要执行权限 在子shell中执行
- #/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
今天的文章shell脚本语言是什么_shell脚本用什么语言编写[通俗易懂]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86872.html