01Shell脚本入门:基础命令与变量解析
什么是shell
shell是命令解释器,负责解释用户输入的命令传递给内核,内核执行调用硬件,然后将结果返回给shell
linux的默认shell是bash
Shell分交互式与非交互式
交互式:输入命令可以得到响应
非交互式:通过脚本运行Shell命令,无需等待用户输入命令
什么是 Shell脚本
将命令写入到文件中,称为 shell脚本。增加了判断循环函数等语法
创建第一个shell脚本
[root@laoli ~]# mkdir -p shell
[root@laoli ~]# cd shell
[root@laoli shell]# touch test.sh
[root@laoli shell]# cat test.sh
#!/bin/bash
echo hello
[root@laoli shell]# . test.sh
hello
执行shell脚本的三种方式:
1,sh 或 bash,不需要执行权限,在子shell中执行
[root@laoli shell]# sh test.sh
hello
[root@laoli shell]# bash test.sh
hello
2,路径执行方式: 需要给脚本增加执行权限,在子shell中执行
[root@laoli shell]# ll
total 4
-rw-r--r--. 1 root root 23 Aug 23 04:27 test.sh
[root@laoli shell]# chmod +x test.sh
[root@laoli shell]# /root/shell/test.sh
hello
3, 点 . 或者source执行脚本,不需要执行权限,在父shell中执行
[root@laoli shell]# . test.sh
hello
[root@laoli shell]# source test.sh
hello
解释器分为父shell和子shell
父shell: 登录系统默认为父shell
子shell: 在默认的父shell中执行bash 进入到了一个子shell中在执行脚本的时候,调用子shell执行内容
其他的shell脚本执行方式
[root@laoli shell]# bash < test.sh
hello
[root@laoli shell]# cat test.sh|bash
hello
Shell变量
1:什么是变量?
用一个固定的值表示一堆不固定的值,称为变量
2:变量的分类:
环境变量(全局变量),对于系统所有的bash生效,默认系统定义好的,都是大写
普通变量(局部变量),自己来定义的变量,一般都在脚本文件中定义
全局变量先生效,局部变量后生效,所以全局变量与局部变量重复时候,局部变量生效
3:按照变量的生存周期
1.临时变量:只在当前的shell中生效
使用export定义,则变量在全局(所有shell)生效,但是其他连接的会话不会生效
2.永久变量:写入到文件中或者/etc/profile变量文件中
4:变量相关的配置文件
/etc/profile 常用的变量配置文件,每次开机和每次的远程连接都会执行此文件
用户变量文件:
.bashrc
.bash_profile
/etc/bashrc
5: 变量定义规则
变量名只能由字母,数字和下划线组成,可以由字母或下划线开头,不能以数字开头,等号两端不允许有空格,尽量不要使用关键字命名变量(和c语言差不多)
6:变量值定义规则
一:字符串定义,通常为连续字符串,如果需要不连续需要加双引号
[root@laoli etc]# name=helloworld
[root@laoli etc]# echo $name
helloworld
[root@laoli etc]# name=hello world
bash: world: command not found...
定义不连续则报错[root@laoli etc]# name="hello world"
[root@laoli etc]# echo $name
hello world----------------------------------------------------------------------------------
定义文件路径
[root@laoli etc]# dir=/etc/sysconfig/network-scripts/ifcfg-eno16777736
[root@laoli etc]# cat $dir
HWADDR=00:0C:29:82:C6:4E
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
NAME=eno16777736
UUID=075c43f5-42b0-4725-b27b-a3e85c8b2c75
ONBOOT=yes
IPADDR=192.168.74.128
GATEWAY=192.168.74.2
DNS1="8.8.8.8"
----------------------------------------------------------------------------------
定义命令
[root@laoli etc]# hehe="echo hehe"
[root@laoli etc]# $hehe
hehe
二:数字定义,不连续需要加双引号
[root@laoli etc]# age=18
[root@laoli etc]# echo $age
18[root@laoli etc]# idcard=3230230230
[root@laoli etc]# echo $idcard
3230230230[root@laoli etc]# idcard=32302 30230
bash: 30230: command not found...
#不连续报错,需要加双引号
[root@laoli etc]# idcard="32302 30230"
[root@laoli etc]# echo $idcard
32302 30230
三:命令定义
[root@laoli etc]# test01=`pwd`
[root@laoli etc]# echo $test01
/etc
先执行``里的命令,把结果赋值给test01[root@laoli etc]# test01=pwd
[root@laoli etc]# $test01
/etc
将命令赋值给变量,变量值本身现在就代表这个命令[root@laoli etc]# test01='pwd'
[root@laoli etc]# echo $test01
pwd
查看变量看的是字符串,echo后面跟的全是字符串案例: 定义一个变量,在脚本任意的位置执行nginx -t命令
[root@laoli nginx]# nginx_n='nginx -t'
[root@laoli nginx]# $nginx_n
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
补充:
Time=`` # 将执行后的结果赋值给Time
Time=$() # 将执行后的结果赋值给Time双引号可以解析变量
[root@laoli nginx]# test02="$test01"
[root@laoli nginx]# echo $test02
pwd变量之间要加{}
[root@laoli nginx]# ip=10.0.0.1
[root@laoli nginx]# host=web01
[root@laoli nginx]# echo "$ip_$host"
web01
不加括号无法都显示出来[root@laoli nginx]# echo "${ip}_$host"
10.0.0.1_web01
Shell核心位置变量
$n 获取脚本的第n个参数
$0 代表脚本本身名称,如果执行脚本带路径,则名称也带路径。
[root@laoli shell]# cat test.sh
#!/bin/bash
echo 123
echo $0
[root@laoli shell]# . test.sh
123
bash
$n 获取脚本的第n个参数,$0被名字占用,从$1开始,可以传递数字、字符串和序列
$1 表示脚本的第1个参数
$7表示脚本的第7个参数
注意:从10开始,参数要用{ }引起来,否则不能正常传参,例如${10},${11}
[root@laoli shell]# cat test.sh
#!/bin/bash
echo $1 $2 $4[root@laoli shell]# . test.sh 1 2 3 4
1 2 4
没有$3则跳过.未传参的变量默认为空[root@laoli shell]# cat test.sh
#!/bin/bash
[root@laoli shell]# . test.sh 'hello world' 2
hello world 2
单引号中的字符串为一个变量的值[root@laoli shell]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
[root@laoli shell]# . test.sh {a..z}
a b c d e f g h i j k[root@laoli shell]# cat test.sh
#!/bin/bash
echo name:$1
echo age:$2
[root@laoli shell]# . test.sh lisan 23
name:lisan
age:23
$# 获取脚本的传参个数
[root@laoli shell]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
echo $#
[root@laoli shell]# . test.sh {a..f}
a b c d e f
6
只传了6个参数,所以显示六个值,$#为6案例: 判断传入参数必须为2个,否则提示错误[root@laoli shell]# cat test.sh
#!/bin/bash
[ $# -ne 2 ]&&echo '请输入两个参数'&&exit
echo name: $1
echo age: $2
[root@laoli shell]# . test.sh laoli 23
name: laoli
age: 23
[root@laoli shell]# . test.sh laoli
请输入两个参数
shell中的比较运算符
shell中,-eq表示等于 , -ne表示不等于
与变量结合时的格式:在 [ ]
中使用时,变量和运算符前后必须有空格,例如 [ $a -eq $b ]
不能写成 [$a-eq$b]
。
返回值:条件成立时返回状态码 0
(真),不成立时返回非 0
(假),符合 Shell 命令的通用规则
案例: 判断传入参数必须为2个,否则提示错误-eq写法#!/bin/bash
[ $# -eq 2 ] || { echo '请输入两个参数'&&exit ;}
echo name: $1
echo age: $2-ne写法#!/bin/bash
[ $# -ne 2 ] && echo "请输入两个参数" && exit
echo name: $1
echo age: $2
补充:常见的命令连接符&&和||
&&
(逻辑与):前真后行,结合规则遵循从左到右(左结合)
意思就是左边的为真才执行右边的
||
(逻辑或):前假后行,结合规则遵循从左到右(左结合)
意思就是左边的为假才执行右边的
获取脚本传参的所有参数$* ; $@
$* 获取脚本传参的所有参数,默认和$@相同,在循环体中加双引号表示一个整体
$@ 获取脚本传参的所有参数,默认和$*相同,在循环体中加双引号表示独立的参数
[root@laoli shell]# cat ceshi.sh
#!/bin/bash
echo $1 $2 $3
echo $*
echo $@
echo $#
[root@laoli shell]# . ceshi.sh 1 2 3
1 2 3
1 2 3
1 2 3
3
Shell状态变量:
$? 存储上条命令执行结果,成功为0,失败不为0
案例: 通过传参的方式传入域名,然后ping是否在线[root@laoli shell]# cat ceshi.sh
#!/bin/bash
ping -c1 -w1 $1 &>/dev/null
[ $? -eq 0 ]&&echo "$1 tong"||echo "$1 butong"
[root@laoli shell]# . ceshi.sh www.baidu.com
www.baidu.com tong
$$ 获得脚本的pid号
[root@laoli shell]# cat get_pid.sh
#!/bin/bash
echo $$
[root@laoli shell]# . get_pid.sh
23717
$! 获取上一个在后台运行脚本的PID号
$_ 获取脚本的最后一个参数
小结:
$0 获取脚本名称
$n 获取脚本n个参数 $1开始
$# 获取传参的总个数
$? 获取上一条命令的执行结果 0成功 非0 失败
$$ 获取脚本的PID号
$! 获取上一个在后台运行的脚本PID号
$* 获取所有传参的参数
$@ 获取所有传参的参数
Shell传参三种方式:
1:直接传参
[root@laoli shell]# cat chuancan.sh
#!/bin/bash
echo $1 $2
[root@laoli shell]# . chuancan.sh 1 2
1 2
2:赋值传参
[root@laoli shell]# cat chuancan.sh
#!/bin/bash
a=$1
b=$2
echo name:$a
echo age:$b
[root@laoli shell]# . chuancan.sh cx 12
name:cx
age:12
3:read交互式传参
这个和python的input语句很像,read -p可以输入提示语
直接执行脚本不需要参数,进入脚本后开始交互式传参
[root@laoli shell]# cat chuancan.sh
#!/bin/bash
read -p 'write your name:' a
echo name:$a
[root@laoli shell]# . chuancan.sh
write your name:cxk
name:cxk
这是我的个人学习笔记,主要用于记录自己对知识点的理解和梳理。由于目前仍在学习探索阶段,内容中难免存在理解偏差或表述疏漏,恳请各位大佬不吝赐教,多提宝贵意见~ 若有不同看法,欢迎理性交流探讨,感谢包容与指正!