#Ubuntu#__shell脚本命令,expect交互工具,coredump设置等常用功能
一、shell脚本解释器
#必须写在shell脚本的第一行
#!/bin/bash #linux标准的shell脚本解释器,linux默认解释器,可兼容sh
#!/bin/sh #unix标准的shell脚本解释器,不可兼容bash
#!/usr/bin/expect #expect交互工具的解释器,在终端通过“expect expect.sh”命令执行脚本
其中#!是特殊的表示符,用于定义shell脚本的解释器类型,#!之后的内容为解释器在本地的路径。
除了上述的解释器之外,还可以有其他类型解释。
二、shell脚本常用功能
一) if语句
#用法1
if [判断条件];then #判断条件用[]括起来
statement1
statement2
fi #if条件判断结束的命令
#用法2
if [判断条件];then #判断条件用[]括起来
statement1
statement2
else
statement3
statement4
fi #if条件判断结束的命令
#用法3
if [判断条件];then #判断条件用[]括起来
statement1
statement2
elif
statement3
statement4
fi #if条件判断结束的命令
二) shell脚本中注释多行的方法
:<<eof #eof是标记符,和最后的相同,可以换为其他的的字母
…
eof
三)shell脚本中命令封装符号
``(反引号)和$()都是shell脚本中封装一段命令的符号,如果一些命令需要封装成一句话,则可以通过这两种符号进行封装,比如:
ls_conten=`ls $PWD`
ls_conten=$(ls $PWD)
- 注意事项
在``(反引号)和$()中,反斜杠“\”符号(转义字符)的解析不一样
- 在``(反引号) 中:\=\
- $()中:=\,反斜杠含义正常
echo `ls \$PWD` # 打印当前路径名称
echo $(ls \$PWD) # 打印“$PWD”字符
echo `ls \\$PWD` # 打印“$PWD”字符
echo $(ls \\$PWD) # 打印当前路径名称
四)脚本中自动输入密码
通过sudo -S命令实现脚本内自动输入密码,其中-S表示的从标准输入中读取密码,更多关于sudo的使用可以sudo --help查阅
# 方式1:
system_password=123456
sudo -S cp ./file.txt /etc/ << EOF
${system_password}
EOF
# 方式2:
system_password=123456
echo ${system_password}|sudo -S cp ./file.txt /etc/
五)将字符串当成一段命令执行
通过bash -c或sh -c实现,其中-c表示的是后面接的内容(使用单引号包含在内)当做command来执行,注意:此时在单引号内不能使用单引号外脚本定义的局部变量,否则会无法正确传入参数
bash -c 'exe_name=app; echo ${exe_name} << /etc/config'
六)添加程序的可执行文件为环境变量
通过export命令将可执行文件所在路径添加到环境变量中,并且将该命令添加到bashrc文件中,bashrc文件会在每次启动终端的时候自动执行,这样可以保证在终端可以直接输入可执行文件名称执行该程序。
- 在终端打开环境配置文件
sudo gedit ~/.bashrc - 在打开的文档末尾添加程序所在路径,例如:
export PATH=/home/hhs/tool:$PATH - 保存文档并退出,然后在终端输入下属命令使功能立即生效
source ~/.bashrc - 在任意终端可以直接输入对应的可执行文件,即可运行
七)终端快捷命令设置
使用较短的命令代替常用的长命令,以便在终端操作的时候,不用每次都输入很长的命令,提高操作效率。
通过alias命令实现短命令替换长命令的功能,然后将该语句写入到bashrc文件中,具体操作如上面所述。
例子:通过connect代替ssh root@168.31.1.45登录远程系统的命令,将下述命令保存到bashrc文件中,source之后在终端中可以直接输入connect就表示执行ssh root@168.31.1.45。
alias connect='ssh root@168.31.1.45'
八)修改文件权限和拥有用户(chmod和chown)
- 添加文件权限,包括读(r)、写(w)和运行(x)
sudo chmod 777 filename #为文件添加所有权限
sudo chmod -777 filename #为文件删除所有权限
sudo chmod +rwx filename #为文件添加所有权限,可以单独添加某项权限
sudo chmod -rwx filename #为文件删除所有权限,可以单独删除某项权限 - 去掉文件夹右下角的锁
sudo chown username:username foldername
chmod:用于改变文件或目录的访问权限,该命令有两种用法。一种是包含字母和操作符表达式的文字设定法;另一种是包含数字的数字设定法。
(1)文字设定法
语法:“chmod [who] [+ | - | =] [mode] 文件名”
操作对象who可是下述字母中的任一个或者它们的组合:
u 表示“用户(user)”,即文件或目录的所有者。
g 表示“同组(group)用户”,即与文件属主有相同组ID的所有用户。
o 表示“其他(others)用户”。
a 表示“所有(all)用户”。它是系统默认值。
操作符号可以是:
+,添加某个权限。
-,取消某个权限。
=,赋予给定权限并取消其他所有权限(如果有的话)。
mode 所表示的权限可用下述字母的任意组合:
r,可读。
w,可写。
x,可执行。
文件名:以空格分开的要改变权限的文件列表,支持通配符。
在一个命令行中可给出多个权限方式,其间用逗号隔开。例如:chmod g+r,o+r example,表示使同组和其他用户对文件example 有读权限。
(2)数字设定法
语法:“chmod [三个八进制数字] 文件”,这三个八进制数字从左到右分别表示了(u)(g)(o)的操作权限。
比如chmod 777 mm.txt,表示给mm.txt文件设置所有的权限。
将rwx看成二进制数,如果有权限记为1,没有权限记为0,那么“可读可写可执行”,则对应于rwx这三个位置上全是1的情形,即111,化为八进制即为7;换句话说,数字7表示“可读可写可执行”;“可读可写不可执行”,则对应于rwx=110的情形,即6;换句话说,数字6表示“可读可写不可执行”。
当我们还不熟悉某个数字表示什么权限时,可以把它分解为二进制数字,然后对应rwx的位置,就可以知道这个数字具体表示什么权限信息。
r,具有读取文件内容的权限;具有浏览目录的权限。
w,具有新增、修改文件内容的权限;具有删除、移动目录内文件的权限。
x,具有执行文件的权限;具有进入目录的权限。
chown: 英文全拼为change owner,命令用于设置文件所有者和文件关联组的命令。
Linux/Unix 是多人多工操作系统,所有的文件皆有拥有者。利用 chown 将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户 ID,组可以是组名或者组 ID,文件是以空格分开的要改变权限的文件列表,支持通配符。
chown 需要超级用户 root 的权限才能执行此命令。
调用格式:chown [-cfhvR] [–help] [–version] user[:group] file…
user : 新的文件拥有者的用户名或使用者 ID
group : 新的文件拥有者的用户名或使用者组(group)
-c : 显示更改的部分的信息
-f : 忽略错误信息
-h :修复符号链接
-v : 显示详细的处理信息
-R : 处理指定目录以及其子目录下的所有文件
–help : 显示辅助说明
–version : 显示版本
例子:
chown root:root file1.txt,表示文件file1.txt的拥有用户和群体使用者都设置root用户
九)通过终端关机
关机
1、halt #立刻关机
2、poweroff #立刻关机
3、shutdown -h now #立刻关机(root用户使用)
4、shutdown -h 10 #10分钟后自动关机 如果是通过shutdown命令设置关机的话,可以用shutdown -c命令取消重启
重启
1、reboot #立刻重启
2、shutdown -r now #立刻重启(root用户使用)
3、shutdown -r 10 #过10分钟自动重启(root用户使用)
4、shutdown -r 20:35 #在时间为20:35时候重启(root用户使用) 如果是通过shutdown命令设置重启的话,可以用shutdown -c命令取消重启
十)export命令:添加环境变量
如果该命令是在终端中执行该命令,则只在该终端产生作用,该终端关闭后失去作用。大部分的是都是用于设置PATH环境变量,用于添加路径到系统,使得系统能够搜索到对应路径下的文件。
如果需要将环境变量加到系统里,可以将该命令添加到profile文件或bashrc文件中,修改完profile文件或bashrc文件需要使用source命令使环境变量立刻加载到系统。
export PATH=$PATH:/opt/au1200_rm/build_tools/bin
//等效于
export PATH=/opt/au1200_rm/build_tools/bin:$PATH
十一)alias命令:设置别名
用于设置别名,主要作用是设置短的命令来替代一些常用的长命令,以缩短每次输入的命令。如果是在终端执行该命令,则只在当前终端有效,随着终端关闭而失效。可以将该命令写到bashrc文件中,这样在每次打开终端都能够使用短命令来替代对应的长命令。
alias 短命令='原始长命令' #注意等号两边不要有空格
alias connect_iecu='ssh root@192.168.1.70'
unalias connect_iecu #删除设置的别名
alias -p #查看所有的别名
十二)ln命令:建立软连接
用于设置软连接,以实现在非硬连接路径下链接到其他的文件系统中。如果在映射目录下空间不足时,可以添加软连接,达到使用其他目录下面的空间。
具体的使用如下所示,并使用绝对路径来设置软链接,即原目录和映射目录使用绝对路径。
ln -s 原目录 映射目录 #在映射目录下会生成一个文件,进入该文件会自动链接到原目录下
sudo rm -rf 软连接 #在映射目录下能看到软连接的名称,并在该路径下打开终端,输入该命令删除对应软连接
ln -s /opt/vscode /home/gdc
十三)apt-get命令:库更新
#1. 系统库更新
sudo apt-get update
sudo apt-get upgrade
#2. 依赖库安装:一般用于自动安装待安装软件的依赖库
sudo apt-get -f install #先输入需要安装软件的安装命令,提示需要依赖库时再输入这个命令
十四)passwd命令:修改系统密码
在终端输入下述命令,可以不受限制的修改任意形式密码,如果不加sudo,则需要安装系统提示设置足够复杂的密码。输入下述命令后会弹出相应对话,按对话修改密码即可。
sudo passwd username #根据实际情况将username改为本机电脑用户名
十五)tar压缩和解压文件
# 压缩:
sudo tar zcvf work.tar.gz work/
sudo tar jcvf work.tar.bz2 work/
sudo tar cvf work.tar work
# 解压:
ls *.tar.gz | xargs -n1 tar xzvf # 批量解压文件
tar xzvf work.tar.gz
tar xjvf work.tar.bz2
tar xvf work.tar
tar xvf work.tar.xz
tar xf work.tar.xz
tar xf work.tar.xz 和 tar -xf work.tar.xz是等效的,-xf和xf是一样的,其他更详细的操作参见
十六)md5sum命令:查看文件的md5值
md5值是对文件的明文密码进行加密后的密码,也称为“数字指纹”,与文件一一对应,如果文件被修改了,那么md5值也会发生变化,因此可以通过md5值查看文件是否被修改。
通过md5sum命令查看文件的md5值,对比2个文件的MD5值,可以判断2个软件是否完全一致。
md5sum filename # 返回对应文件的md5值
十七)获取系统架构(x86或arm)
architecture=$(uname -a | awk -F " " '{print $(NF-1)}')
echo ${ architecture} # x86_64或aarch64
十八)在shell脚本中起terminal
gnome-terminal -x bash -c “cd path; mkdir 123”:新起一个终端,然后执行双引号中的命令
三、expect交互工具
一) 作用
在shell脚本中实现本地与远程服务器的交互,可以实现ssh、scp等与远程服务器交互的命令;可以嵌入到正常的shell脚本中,使用“#!/bin/bash”解释器即可,也可以直接使用“#!/usr/bin/expect”解释器,此时脚本中只能使用expect相关的命令。
主要用于自动化实现本地与远程服务的交互操作,可以用于软件版本部署,在远程服务器进行程序编译等操作。
二) 安装
通过终端安装,安装命令如下:
sudo apt-get install expect
三) 常用命令
- Expect中常用的几个命令是spawn、expect、send、interact、expect eof,详细的使用见后面的例子。
spawn:启动新的进程,比如通过spawn启动了一个ssh服务
expect:从进程接收字符串
send:用于向进程发送字符串
interact:用于expect命令需要结束的时候,实现执行完成expect命令后保持远程交互状态,把控制权交给控制台,这个时候就可以手工在终端进行操作了。
expect eof:用于expect命令需要结束的时候,等待结束标志,用于等待spawn进程中命令结束时标志。
备注:expect命令结束后必须加interact或expect eof,否则可能会导致最后一句expect命令没有执行完就退出脚本。
- 在shell脚本中插入expect命令
#!/bin/bash
......
#在普通shell脚本中插入expect命令
expect << EOF #EOF可以换为其他的符号,末尾的时候保持一致即可
expect 命令
EOF
......
- 设置命令执行时间
set timeout 30 #设置shell脚本中每行命令执行超时时间为30秒
set timeout -1 #设置shell脚本中每行命令执行超时时间为无限长
四) 使用案例
例子1:直接通过expect解释器来执行expect脚本
#!/usr/bin/expect #选择脚本解释器,在做终端输入expect expect.sh运行脚本
set timeout 30 #设置脚本中每行命令的运行的超时时间为30s
......
例子2:在普通shell脚本中插入expect命令
#!/bin/sh
host_ip="168.31.1.75"
username="root"
password="123456"
src_file="/folder/files/"
# 1. 登录远程服务器,并进行相关的操作
expect << EOF
set timeout -1
spawn ssh $username@$host_ip
expect {
"(yes/no)?" { send "yes\n" }
"*password:" { send "$password\n" }
}
expect "#*" { send "rm -rf file \r" }
expect "#*" { send "exit \r" }
expect eof
EOF
# 2.拷贝本地文件到远程服务器
expect << EOF
set timeout -1
spawn scp OD.tar.gz $username@$host_ip:$src_file
expect "*password:" { send "$password\n" }
expect eof
EOF
四、设置coredump权限
一)在程序测试的时候允许生产core文件
如果只是需要在测试的时候允许程序生成core文件,则按下述方式进行设置,注意,此时需要修改/proc/sys/kernel/core_pattern文件,可以通过sudo gedit或者是下述的方式修改,使用sudo vi无法修改(因为/proc/sys/下面的文件为内存镜像文件):
system_password=123456
# 设置core文件的大小,unlimited表示不限制,也可以设置为具体大小
ulimit -c unlimited
# 设置core文件生成路径和命名格式
echo ${system_password} | sudo -S sh -c 'core_dump_file=/home/igs/core_dump/core-%e-%p-%h-%t; echo ${core_dump_file} > /proc/sys/kernel/core_pattern'
# core文件命名格式
%p - insert pid into filename 添加pid
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加名字
二)设置系统允许所有程序(除了系统程序)生成core文件
如果是需要设置系统允许程序生成core文件,则按下述方式进行设置,注意设置好之后需要重启系统才能生效
- 将ulimit -c unlimited添加到/home/host_name/.bashrc.sh文件末尾
- 将kernel.core_pattern = /home/igs/core_dump/core-%e-%p-%h-%t写入到/etc/sysctl.conf文件中(重启生效)
三)设置允许系统程序生成core文件
针对ubuntu的系统控制的进程,则需要将coredump设置添加到.service结尾的启动配置文件中,详见参考博客(本人未测试过)
五、shell脚本中读取文档
在shell脚本中读取txt或csv文档,有多种方式,下面列举2种遍历全文的方法,以及截取文中指定行内容的方法。
一)通过while+read实现
file=./test.txt
while read line; do
echo ${line}
done < ${file}
二)通过for循环实现
file=./test.txt
for str in `cat ${file}`; do
echo ${str}
done
三)通过head和tail命令读取文本中部分内容
file=test.txt
# 读取文本最后3行内容
str=`tail -n 3 ${file}`
# 读取文档倒数第3行内容
str=`tail -n 3 ${file} | head -n 1 `
# 读取文本开头3行内容
str=`head -n 3 ${file}`
# 读取文档第3行内容
str=`head -n 3 ${file} | tail -n 1 `
六、字符串处理
在一个字符串中截取部分字符,参考博客整理如下八种处理方式
一)“#”截取,删除左边字符,保留右边字符。
var=http://www.aaa.com/123.htm
echo ${var#*//}
其中,var是变量名,# 是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
删除 :http://
**结果:www.aaa.com/123.htm **
二)“## ”截取,删除左边字符,保留右边字符。
var=http://www.aaa.com/123.htm
echo ${var##*/}
其中,var是变量名,## 是运算符,*/ 表示从左边开始删除最后一个(最右边) / 号及左边的所有字符
删除:http://www.aaa.com/
结果:123.htm
三)“%”截取,删除右边字符,保留左边字符
var=http://www.aaa.com/123.htm
echo ${var%/*}
其中,var是变量名,%是运算符,/* 表示从右边开始,删除第一个 / 号及右边的字符
删除:/123.htm
结果:http://www.aaa.com
四)“%%”截取,删除右边字符,保留左边字符
var=http://www.aaa.com/123.htm
echo ${var%%/*}
其中,var是变量名,%%是运算符,/* 表示从右边开始,删除最后一个(最左边) / 号及右边的字符
删除://www.aaa.com/123.htm
结果:http:
五)从左边第几个字符开始,截取几个字符
var=http://www.aaa.com/123.htm
echo ${var:0:5}
其中,var是变量名,0表示从左边第1个字符开始,5 表示向右边方向截取字符的数量。
结果:http:
六)从左边第几个字符开始,截取到结束的字符
var=http://www.aaa.com/123.htm
echo ${var:7}
# 左边第一个字符
echo ${var:0}
其中,var是变量名,7 表示从左边第8个字符开始。
结果:www.aaa.com/123.htm
七)从右边第几个字符开始,截取几个字符
var=http://www.aaa.com/123.htm
echo ${var:0-7:3}
其中,var是变量名,0-7 表示右边算起第七个字符开始,3 表示向右边方向截取字符的数量。
结果:123
八)从右边第几个字符开始,截取到结束的字符
var=http://www.aaa.com/123.htm
echo ${var:0-7}
# 右边第一个字符
echo ${var:0-1}
其中,var是变量名,0-7 表示右边算起第七个字符开始。
结果:123.htm
七、写文本
一)新建或覆盖文本
echo -e中-e表示打开反斜杠 \ 转义,否则下述echo语句中的 \n 无法正确解析
# 方法1:
log_name=log.txt
# 如果文本不存在则新建文本,如果文本存在则覆盖原文
echo -e "\nstart" | tee ${log_name}
# 方法2:
log_name=log.txt
touch ${log_name}
# 下述命令会自动创建文本如果文本不存在的话
# 如果文本不存在则新建文本,如果文本存在则覆盖原文
echo -e "start" > ${log_name}
二)在文本后面添加内容
# 方法1:
log_name=log.txt
# 如果文本不存在则新建文本,如果文本存在则在文末添加一行
echo -e "\nstart" | tee -a ${log_name}
# 方法2:
log_name=log.txt
touch ${log_name}
# 下述命令会自动创建文本如果文本不存在的话
# 如果文本不存在则新建文本,如果文本存在则在文末添加一行
echo -e "start" >> ${log_name}
三)echo增加root权限进行写文件
sh是执行shell脚本的命令,和bash等效,-c表示将后续接的单引号‘’括起来的字符串当成shell命令来执行,然后通过sudo给sh命令添加root权限即可实现echo给root权限文件写入内容,更多信息参考。
sudo sh -c 'core_dump_file=/home/igs/core_dump/core-%e-%p-%h-%t; echo ${core_dump_file} > /proc/sys/kernel/core_pattern'
八、获取系统时间
# 原始输出
echo `date`
# utc时间,单位s
echo `date +%s`
# 按照自定义格式显示时间
echo `date +%F\ %T`
echo `date +"%F %T"`
echo `date +%Y%m%d-%H:%M:%S`
echo `date +%y-%m-%d-%H-%M-%S`
结果如下:
Sat 23 Apr 2022 05:16:23 PM CST
1650705383
2022-04-23 17:16:23
2022-04-23 17:16:23
20220423-17:16:23
22-04-23-17-16-23
更多的关于date的使用详见帮助说明(date --help),utc时间与gps时间的区别详见
九、加减乘除运算
一)整数加减乘除
#只能进行加减运算
a=2
d=3
a=`expr ${a} + ${d}`
# 可以进行加减和乘除运算,运算符与变量或数字之间不能有空格
let a=${a}+${d}*2
推荐使用下述方式,可以进行加减和乘除运算,运算符与变量或数字之间可以有空格
a=2
d=3
# $(())等效于$[],其中使用的变量可以不适用的$
a=$((${a} + ${d} * 2))
a=$((a + d * 2))
可支持的运算符如下:
+ - * / :分别为 “加、减、乘、除”
% :余数运算
& | ^ !:分别为 “AND、OR、XOR、NOT” 运算
<, >, <=, >=, ==, !=:分别为“小于、大于、小于或等于、大于或等于、等于、不等于”
二)小数加减乘除
a=2.5
b=$(echo "$a * 2 / 0.5 - 2" | bc)
# 如果加减乘除运算没有用双引号括起来,则运算符与数字之间不能有空格
b=$(echo $a*2/0.5-2 | bc)
十、数组的使用
十一、逻辑运算符、逻辑表达式详细介绍
十二、函数使用
shell脚本中定义函数,其中的变量在整个shell脚本中可见的,函数中不能定义局部变量。
function reset_parameter()
{
a=2
b=3
return 1
}
$?是函数的返回值,调用函数之后,立马访问这个数据,如果中间插了其他命令,则$?显示的结果将不再是函数的返回值。