shell【二】

有无export的区别
无export 对当前父shell有效,shell无效
有export 对当前窗口有效

shell变量知识进阶与实践
1)直接赋值

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#变量直接赋值
a=1
b=2
echo $a $b
[root@web01 script]# 

2)传参赋值

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#传参赋值
a=$1
b=$2
echo $a $b
[root@web01 script]# sh test.sh 红烧肉  西红柿炒鸡蛋
红烧肉 西红柿炒鸡蛋

3)交互式赋值

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#交互式赋值
read -p "请输入一个学员名字:" name(变量)
echo $name(调用变量)
[root@web01 script]# sh test.sh
请输入一个学员名字:lsy
lsy
[root@web01 script]# 

企业使用:可以根据需求调整变量,可以便于新员工快速掌握脚本的使用
read命令 -p 参数解释: 阅读命令从标准输入中读取一行,并且把输入行的每个分区的值指定给shell变量
-p 后面跟提示信息,在输入前打印提示信息

脚本中特殊变量说明

01 位置变量作用说明
1 $0 获得脚本名称信息;直接显示脚本名称,或包含脚本的绝对路径
实际应用

2 $n 脚本的第n个参数 ,n表示从1..9 (不能到10),大于9的数量用${10}组合起来

实际应用:识别脚本后面参数信息

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#$n 特殊变量使用方法
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}

[root@web01 script]# sh test.sh 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

3 $# 代表脚本的传参总数信息, 多个传参参数以空格进行分割, 可以用双引号将多个空格分割参数汇总为一个整体 4 $* 输出脚本的所有参数;加上引号信息时,和$@不同,加上引号是看成一个整体 5 $@ 输出脚本的所有参数;加上或者不加引号;都表示将多个参信息看成独立的个体

$0 获得脚本名称信息;直接显示脚本名称

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#显示脚本名称的特殊变量$0
echo $0
[root@web01 script]# sh test.sh
test.sh
[root@web01 script]# sh /server/script/test.sh
/server/script/test.sh
[root@web01 script]# 
[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#显示脚本名称的特殊变量$0
echo Usage: $0  {请输入学生姓名和年龄}
echo "请输入学生姓名:$1"
echo "请输入学生年龄:$2"
[root@web01 script]# sh test.sh  张三 30
Usage: test.sh {请输入学生姓名和年龄}
请输入学生姓名:张三
请输入学生年龄:30
[root@web01 script]# 

扩展:
01 如何获得一个文件所在路径信息:
02 如何只显示一个文件的名称信息:

[root@web01 script]# echo /oldboy/oldboy01/oldboy03/oldboy.txt 
/oldboy/oldboy01/oldboy03/oldboy.txt
[root@web01 script]# echo /oldboy/oldboy01/oldboy03/oldboy.txt |xargs dirname
/oldboy/oldboy01/oldboy03
[root@web01 script]# echo /oldboy/oldboy01/oldboy03/oldboy.txt |xargs basename
oldboy.txt
[root@web01 script]# 

dirname 显示指定路径出了文件名之外的路径前缀
basename 去掉前面的路径,只显示文件名称

$n 脚本的第n个参数
补充:生成序列信息的特殊方法

[root@web01 script]# echo \${1..9}
$1 $2 $3 $4 $5 $6 $7 $8 $9
[root@web01 script]# 

方法二:sep -s (指定分割符–默认是回车为分隔符) 但是第一个有点问题,也就是1在开头,没法执行

[root@web01 script]# seq -s " $" 20
1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20

$# 代表脚本的传参总数信息, 多个传参参数以空格进行分割, 可以用双引号将多个空格分割参数汇总为一个整体
脚本应用:

[ $# -eq 2 ] || echo "Usage: $0 {请写入学生年龄和姓名}"

$*

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#$@ $* 特殊变量使用方法
echo $1 $2 $3
echo $@
echo $*
[root@web01 script]# sh test.sh oldboy oldgirl oldgod lsy 1 2 3 4 5 6 7 8
oldboy oldgirl oldgod
oldboy oldgirl oldgod lsy 1 2 3 4 5 6 7 8
oldboy oldgirl oldgod lsy 1 2 3 4 5 6 7 8

$* 和 $@的区别

演示说明
准备参数变量信息
set – “i an oldboy teacher”

[root@web01 script]# set -- “i an oldboy teacher”
[root@web01 script]# echo $#
4
[root@web01 script]# echo $1
“i
[root@web01 script]# echo $2
an
[root@web01 script]# echo $3
oldboy
[root@web01 script]# echo $4
teacher”

测试$* 和 $@之间的区别 ,不加双引号信息没有任何区别

[root@web01 script]# echo $*
“i an oldboy teacher”
[root@web01 script]# echo $@
“i an oldboy teacher”
[root@web01 script]# 

说明:不加双引号,两者没有任何区别
区别体现在循环体结构中

测试$@ $* 之间的区别 加上引号信息

[root@web01 script]# echo "$@"
“i an oldboy teacher”
[root@web01 script]# echo "$*"
“i an oldboy teacher”
[root@web01 script]#

在循环体中,不加双引号

[root@web01 script]# for i in $@; do echo $i  ;done
i
an
oldboy
teacher
[root@web01 script]# for i in $*; do echo $i  ;done
i
an
oldboy
teacher

没有什么区别

在循环体中,加双引号(环境准备时set – “i am” oldboy teacher)

[root@web01 script]# for i in "$*"; do echo $i  ;done
i an oldboy teacher
说明:将$*识别所有参数汇总成一个整体参数   赋值给循环体中变量i
[root@web01 script]# for i in "$@"; do echo $i  ;done
i an
oldboy
teacher
[root@web01 script]# 

说明:将$@是别所有参数单独进行识别,赋值给循环体中变量i
但是参数设置有双引号,就会是别成响应的一个整体

总结:加上双引号,在循环体中 $* 会将所有参数看成一个整体 $@ 会将所有参数看成多个个体

什么需求 需要用到"$*" 把传参看成一个整体

#分析日志信息
#2020-4-1  error  订单出现异常 
#01: 统计有多少个错误订单 错误出现日期 定订单情况
#$* date=2020-4-1  log_status=error info=订单出现异常 echo $date $订单情况
#02: 将日志中出现错误日志整体显示输出
#"$*" error_info=2020-4-1  error  订单出现异常  

02 状态变量作用说明

1 $? 获取上一个执行结果 成功用0表示  失败用非0表示
2 $$     获取当前pid信息
3 $!     获取上一个程序或脚本后台运行的pid信息
4 $_   获取脚本的最后一个参数信息

1 $? 获取上一个执行结果 成功用0表示 失败用非0表示
实际应用:判断命令是否执行成功

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#$? 判断命令是否成功与否
[ $# -ne 1 ] && echo $0 "{请输入一个域名地址:}" && exit 2
ping  -c 2 $1 >/dev/null 2>1
[ $? -eq 0 ] && echo "this web_name $1 is ok." ||echo "this is web_name $1 is error"
[root@web01 script]# 

3 $! 获取上一个程序或脚本后台运行的pid信息 守护进程方式执行脚本(sh test04.sh &
在这里插入图片描述

[root@web01 script]# cat test.sh
#!/bin/bash
#lsy  output info
#$? 判断命令是否成功与否  普通进程
[ $# -ne 1 ] && echo $0 "{请输入一个域名地址:}" && exit 2
while true
do
ping  -c 2 $1 >/dev/null 2>1
[ $? -eq 0 ] && echo "this web_name $1 is ok." >>/tmp/test_ping.txt ||echo "this is web_name $1 is error" >>/tmp/test_ping.txt
sleep 10
done

#echo $$ >/tmp/test.pid  

有些进程是出现又消失的
有些进程是一直存在的(守护进程)

3)脚本中变量子串说明

${paramter} 返回变量信息内容,将变量内容做解析
实际应用:识别子串变量信息

企业面试题
企业面试题目:
已知一个变量 OLDBOY=“I am oldboy teacher”, 问变量信息字符数量是多少, 如何统计

方法一: 
echo $OLDBOY|wc -L
测试响应效率:
time for n in {1..10000};do char=`seq -s "oldboy" 100`;echo ${char}|wc -L &>/dev/null;done

方法二:
expr length "$OLDBOY"

测试响应效率:
time for n in {1..10000};do char=`seq -s "oldboy" 100`;expr length "${char}" &>/dev/null;done

方法三:  效率最低
echo $OLDBOY|awk '{print length}'
测试响应效率:
time for n in {1..10000};do char=`seq -s "oldboy" 100`;echo "${char}"|awk '{print length($0)}' &>/dev/null;done

企业面试题目:
已知一个变量 OLDBOY="I am oldboy teacher my name is HQ"
请找出字符串长度小于3的信息
方法一:
for i in I am oldboy teacher my name is HQ
do
   [ ${#i} -lt 3 ] && echo $i
done

方法二:
# echo $OLDBOY|xargs -n1|awk '{if(length<3)print}'
I
am
my
is
HQ

方法三:
# echo $OLDBOY|awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'
I
am
my
is
HQ

方法四:
echo $OLDBOY|egrep -wo "[a-Z]{1,3}" 

补充: 识别KaTeX parse error: Expected 'EOF', got '#' at position 45: …ripts 14:52:55]#̲ echo "{oldboy}isok"
linuxisok
[root@web01 scripts 14:53:11]# echo ‘${oldboy}isok’
${oldboy}isok

总结: $字符串  $数字  $符号  ${} --- 避免金庸新著  $() == ``  将引号里面信息命令进行执行 

${#paramter}
返回变量内容字符长度.
# OLDBOY=“I am oldboy teacher”
# echo ${#OLDBOY}
19

测试响应效率:  效率最高
time for n in {1..10000};do char=`seq -s "oldboy" 100`;echo ${#char} &>/dev/null;done
real	0m19.808s
user	0m6.019s
sys	    0m13.647s

${paramter:offset}
在变量中,从指定字符位置开始提取子串到结尾的信息
${paramter:offset:length}
在变量中,从指定字符位置开始提取子串到指定位置结束
补充:子串中offset信息可以从0开始

[root@web01 script]# echo ${OLDBOY::4}
I am
[root@web01 script]# echo ${OLDBOY:0:4}
I am
[root@web01 script]# 

${paramter#word}
从变量开头开始删除最短匹配的word子串信息;留下没匹配的(默认匹配一次)

[root@web01 script]# OLDBOY=abcABC123ABCabc  --匹配到了abc  所以开头的abc没有显示
[root@web01 script]# echo $OLDBOY
abcABC123ABCabc
[root@web01 script]# echo ${OLDBOY#a*c}
ABC123ABCabc
[root@web01 script]# 

从变量开头开始删除最长匹配的wword子串信息。

[root@web01 script]# OLDBOY=abcABC123ABCabc
[root@web01 script]# echo $OLDBOY
abcABC123ABCabc
[root@web01 script]# echo ${OLDBOY##a*C}
abc

${oarameter%word}

[root@web01 script]# echo ${OLDBOY%a*c}
abcABC123ABC
${parameter%%word}
[root@web01 script]# echo ${OLDBOY%%a*c}

[root@web01 script]# echo $OLDBOY
abcABC123ABCabc
[root@web01 script]# echo ${OLDBOY%%C*c}
abcAB

${parameter/string/replace}
使用repliace 信息替换string字符串,并且只替换第一个匹配的信息

[root@web01 script]# OLDBOY="I am  oldboy teacher,I am oldboy linux teacher"
[root@web01 script]# echo $OLDBOY
I am oldboy teacher,I am oldboy linux teacher
[root@web01 script]# echo ${OLDBOY/oldboy/oldgirl}
I am oldgirl teacher,I am oldboy linux teacher
[root@web01 script]# 

${parameter//string/replace}
使用replace信息替换string字符串信息,但是会将所有信息替换

[root@web01 script]# echo ${OLDBOY/oldboy/oldgirl}
I am oldgirl teacher,I am oldboy linux teacher
[root@web01 script]# echo ${OLDBOY//oldboy/oldgirl}
I am oldgirl teacher,I am oldgirl linux teacher

一个/是替换第一个匹配的
两个//是替换所有匹配的信息

${paramter} 返回变量信息内容,将变量内容做解析
实际应用:识别子串变量信息

[root@web01 script]# oldboy=linux
[root@web01 script]# echo $oldboy
linux
[root@web01 script]# echo ${oldboy}
linux
[root@web01 script]# echo ${oldboy}idok
linuxidok
[root@web01 script]# echo ${oldboy}isok
linuxisok
[root@web01 script]# echo $oldboyisok

[root@web01 script]# 
双引号 可以识别变量  ;单引号所见即所得,无法解析变量
[root@web01 script]# echo "${oldboy}isok"
linuxisok
[root@web01 script]# echo '${oldboy}isok'
${oldboy}isok
[root@web01 script]# 

表示运算 $[]

[root@web01 script]# echo $[1+4]
5
[root@web01 script]# time for n in {1..10000};do char=`seq -s "oldboy" 100` ;echo ${#char} &>/dev/null ; done

real	0m16.820s
user	0m6.243s   用户态
sys	0m10.491s          内核态
[root@web01 script]# 

如何利用替换子串信息,批量修改文件名称
准备环境:

[root@web01 oldboy]# ll
total 0
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_01_linux.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_02_linux.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_03_linux.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_04_linux.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_05_linux.txt
[root@web01 oldboy]# 
[root@web01 oldboy]# for i in `ls |xargs -n1` ;do mv $i ${i/_linux} ;done
[root@web01 oldboy]# 
[root@web01 oldboy]# ll
total 0
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_01.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_02.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_03.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_04.txt
-rw-r--r-- 1 root root 0 Apr  1 04:39 oldboy_2020_05.txt

4)脚本中变量替换说明
${parameter:-word}

在这里插入图片描述

当调取变量信息的值为空时或者未赋值,就返回word字符信息
作用说明:如果变量未定义,则返回备用字符串信息,防止变量为空值或者未定义导致异常
${parameter:=word}
作用说明:如果变量未定义,则设置指定字符串为

[root@web01 oldboy]# lead=孙俪
[root@web01 oldboy]# echo $lead
孙俪
[root@web01 oldboy]# unset lead
[root@web01 oldboy]# echo $lead
[root@web01 oldboy]# echo ${lead:-替演}
替演
[root@web01 oldboy]# echo ${lead:=周迅}
周迅
[root@web01 oldboy]# echo $lead
周迅
[root@web01 oldboy]

说明:如果变量未定义,用指定字符串直接给变量赋值

${parameter:?word}
当调取变量信息的值为空时或者未赋值,错误提示信息word

[root@web01 oldboy]# echo $OLDBOY

[root@web01 oldboy]# echo ${OLDBOY:?此变量未进行赋值设置}
-bash: OLDBOY: 此变量未进行赋值设置
[root@web01 oldboy]# 

${parameter:+word}
当调取变量信息值为空时或者未赋值,不做任何处理,否则word字符串将替代变量值

[root@web01 oldboy]# oldboy=${oldgirl:+linux69}
[root@web01 oldboy]# echo $oldboy

[root@web01 oldboy]# oldgirl=python
[root@web01 oldboy]# oldboy=${oldgirl:+linux69}
[root@web01 oldboy]# echo $oldboy
linux69
[root@web01 oldboy]#

总结:
如果变量未定义,调取变量信息时,不会有任何显示
如果变量已经定义,调取变量信息时,会显示指定字符串信息

?word: 变量未定义提示错误信息; 变量已定义显示变量信息
+word: 变量未定义不做任何处理; 变量已定义显示提示信息

发布了224 篇原创文章 · 获赞 19 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42506599/article/details/105255939