shell脚本

shebang
#!开头的文件,程序会在执行时会调用/bin/sh,bash的解释器。
默认使用/bin/sh执行。
也可指定使用解释器,如: /bin/bash/python hello.py

执行脚本的方式

  1. bash script.sh或者sh script.sh,文件本身没有执行权限的方法。
  2. 使用绝对路径或相对路径,需要文件有执行权限。

shell变量
shell脚本中,变量与值之间不能有空格。
变量命名规则:

  1. 数字、字母、下划线
  2. 不能以数字开头
  3. 严格区分大小写

环境变量:也称全局变量。
特殊变量:$?,若返回0.则上一条命令执行成功;若返回1-255则不成功。

单引号变量:不识别特殊语法。
双引号变量:能识别特殊语法。
例:

[root@localhost ~]# name=wukong
[root@localhost ~]# name1='${name}'
[root@localhost ~]# name2="${$name}"
[root@localhost ~]# echo ${name}
wukong
[root@localhost ~]# echo ${name1}
${name}
[root@localhost ~]# echo ${name2}
wukong

关于sh

  1. 每次调用bash/sh解释器执行脚本,都会开启一个子shell,因此不会保留当前shell变量,通过pstree查看进程树。
  2. 调用source或者点符号,在当前shell环境执行脚本,变量保存。
    linux中,反引号中的命令执行结果讲会被保留。
    文件~/.bash_prpfile --> 用户个人配置文件。

环境变量加载顺序

  • ssh登录linux,启动一个bash shell
  • 加载/etc/profile --> 全局环境变量:为系统中每一个用户设置环境信息。
  • 读取/etc/profile.d目录下脚本。有系统诸多脚本,也有自定义需要登录加载的脚本。
  • 运行$HOME/.bash <-- 用户环境变量文件
  • 运行$HOME/.bashrc
  • 运行/etc/bashrc

特殊变量
$0:获取shell脚本文件名。
$1、$2……$n:获取脚本的第1、2……n个参数,大于9则需要写大括号,如:${10}。
$#:接受到的参数个数。
$*:接收所有参数合并为一个字符串。
$@:不加引号,效果如上。加引号,接收所以参数为独立字符串,空格保留。
$和$@的区别如下:

[root@localhost bin]# sh special1_difference.sh welcome to Jiaxing
print each param from "$*"
welcome to Jiaxing
print each param from "$@"
welcome
to
Jiaxing

special1_difference.sh脚本代码如下:

echo "print each param from \"\$*\""
for var in "$*"
do 
	echo "${var}"
done

echo "print each param from \"\$@\""
for var in "$@"
do
        echo "${var}"
done

特殊状态变量
$?:上次命令状态结果返回,0执行成功,非0失败。
$$当前shell脚本的进程号。
$!上次后台进程的PID。
$_取得上次命令传入的最后一个参数(字面意思)。
shell字串的用法

  1. ${变量} 返回变量值。
  2. ${#变量} 返回变量长度,字符长度。
  3. ${变量:start} 返回变量start之后的字符。
  4. ${变量:start:length} 返回start之后length限制的字符串。
  5. ${变量#word} 从变量开头,删除最近匹配的word子串。
  6. ${变量##word} 从变量开头,删除最远匹配的word子串。
  7. ${变量%word} 从变量结尾,删除最近匹配的word子串。
  8. ${变量%%word} 从变量结尾,删除最远匹配的word子串。
  9. ${变量/pattern/string} 用string代替第一个匹配的pattern。
  10. ${变量//pattern/string} 用string代替所有匹配的pattern。

删除文件案例

touch chaochao_{15}_finshed.jpg
touch chaochao_{15}_finshed.png //创建文件jpg和png各5个

目标:去掉所有文件的finshed后缀

  1. 利用变量的子串功能。
  2. 利用反引号的功能(反引号取得命令执行结果)。

批量文件名替换如下:
for file_name in 'ls *finshed.*';do mv $file_name 'echo ${file_name//_finshed/}'

特殊shell扩展变量

  1. result=${parameter:-word}若parameter变量值为空,返回word赋值给result。
  2. result=${parameter:=word}若parameter变量值为空,则用word替代并且赋值给result。
  3. ${parameter:?word}若parameter变量值为空,word当作stderr输出。
  4. ${parameter:+word}若parameter变量值为空,什么都不做,否则返回word。

创建进程列表(创建子shell)
shell的进程列表理念,需要使用小括号(),如:(命令)。
如上执行命令方式就称为进程列表
Linux默认有关shell的变量

  • $BASH_SUBSHELL若是0,则当前shell运行;若非0.则在子shell运行。
    用来检测是否存在子shell运行。
    (cd~;pwd;ls;echo $BASH_SUBSHELL)
[root@localhost ~]# (cd ~;pwd;ls;echo $BASH_SUBSHELL)
/root
anaconda-ks.cfg  bin  cmatrix-1.2a  cmatrix-1.2a.tar.gz  initial-setup-ks.cfg
1
  • 子shell嵌套运行。
[root@localhost ~]# (pwd;echo $BASH_SUBSHELL;(pwd;echo $BASH_SUBSHELL;(pwd;echo $BASH_SUBSHELL)))
/root
1
/root
2
/root
3

内置命令,外置命令
内置命令:在系统启动时就加载入内存,常驻内存,执行效率高,但是占用资源。
外置命令:系统需要从硬盘中读取程序文件,再读入内存加载。
可用type命令测试外置内置
外置命令一定会开启子shell运行,而内置命令是shell的一部分。
执行脚本
echo "date" --> date
echo "`date`" -->2024年 09月 17日 星期二 15:47:55 CST
对于linux特殊符号的整理
${vars}取出变量结果。
$( )在括号中执行命令,且拿到命令的执行结果。
一对反引号 ` ` 效果同上。
()开启子shell执行。
运算操作符运算命令
双小括号操作方法(())((i=i+1))运算后赋值,i=$((i+1))效果一样。
shell脚本中的自定义函数

print_usage(){
printf "please enter an integer\n"
exit 1 //给脚本的执行结果,赋予一个状态码、退出码。
}

--> echo &? --> 1
read -p "文本" firstnum接收用户输入的命令,附带有提示信息。
if语句
if [ xx ]中括号切换必各有一个空格,这是固定语法。
let命令效果等同于双小括号,但双小括号效率更高。
expr模式匹配
冒号:计算字符串的字符数量。
.*任意的字符串重复0次或者多次
expr ycc.png ":" ".*p" --> 5 //ycc.p

  • 例:找出长度小于5的字符串
[root@localhost hu]# for str1 in I am Yu chao ,I teach you to learn Linux.
>   do
>     if [ `expr length $str1` -lt 5 ]
>      then
>         echo $str1
>     fi
>   done
I
am
Yu
chao
,I
you
to

bc命令
结合管道符来运算。、

[root@localhost hu]# num=5
[root@localhost hu]# result=`echo $num*4|bc`
[root@localhost hu]# echo $result
20
  1. echo {1..100}|tr " " "+"将1到100之间的空格符转换成+,再用管道符给bc计算。
  2. seq 100默认以换行符为分隔符。
    seq -s "+" 100以+为分隔符。

test命令

  1. 针对文件类型判断
  2. 针对文件权限判断
  3. 针对文件的修改时间,数值大小比较,字符串比较。

[]中括号的条件测试
test和中括号[]作用一样,但中括号前后必须有空格.
在条件测试中使用变量必须用双引号.

posted @   MrNegev  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示