文章目录
- 1.shell语法:Shell是用C语言编写的程序,它是用户使用Linux的桥梁,硬件>内核(os)>shell>文件系统
- 1.1 变量:readonly定义只读变量,unset删除变量
- 1.2 函数:shell脚本传递的参数中包含空格,应使用单引号或双引号将该参数括起来,以便于脚本将这个参数作为整体来接收。if [ -n str1 ] 当字符串的长度大于0时为真(字符串非空)
- 1.3 运算:算术、关系、布尔、逻辑、字符串、文件运算
- 1.4 流程控制:if、for、while、case
- 2.ssh_tool:sed -i 's/\r//g' 文件(删除从txt复制来代码的换行符)
- 3.build_bmc:To go back to default recipes: devtool reset linux-aspeed , devtool reset u-boot
- 4.环境变量:用bash调用脚本的时候会创建一个和自己一模一样的shell子进程执行这个外部命令。这个子进程中设置了自己的运行的环境变量,此时父进程的环境变量并没有改变。bash test.sh == ./test.sh。
- 5.scp_image:不用管STRING1
- 6.bmc_upgrade:断电重启才从主启,当前永远mtd4
- 7.自动升级bmc:AC ON物理上电
1.shell语法:Shell是用C语言编写的程序,它是用户使用Linux的桥梁,硬件>内核(os)>shell>文件系统
1.1 变量:readonly定义只读变量,unset删除变量
如果字符串中有空格,必须需要使用引号(str=hello world会报错)。
获取字符串长度:echo ${#str}
,expr length “${str}”
。
截取字符串:echo ${str:1:4}
:显示字符串第1到第4个字符。
echo ${str:4}
:从左边第4个字符开始,一直到结束。
echo ${str:0-6:3}
:从倒数第6个字符开始的3个字符。
echo ${str:0-6}
:从倒数第6个字符开始,一直到结束。
file=/dir1/dir2/dir3/my.file.txt
${file#*/}:删掉第一个 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt / 可换成 . 即#*.
${file##*/}:删掉最后一个 / 及其左边的字符串:my.file.txt
${file%/*}:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:删掉第一个 / 及其右边的字符串:(空值)
#!/bin/bash
for i in `ifconfig | grep -o ^[a-z0-9.]*`
do
name=$i
echo $name
ipaddr=$(ifconfig $i|sed -n 2p|awk '{ print $2 }'|tr -d 'addr:') # -d删除
echo http://$1:8080/api/slave -d '{"slave":"'$2${name}'","ip":"'${ipaddr}'"}'
done
如下截取 = 号左边即第一个。
"-d")
shift
case ${1} in
"lc1" | "lc2" | "cmm" | "fb1" | "fb2")
;;
*)
usage
;;
esac
dev=${1}
led_devie=${dev%[^a-zA-Z]} # lc
if [ "$1" != "cmm" ];then
index=${dev/*[a-zA-Z]/} # 1
fi
;;
设置别名,printf,重定向,exit,until,shift,basename/dirname
不添加引号,转义将不被执行,如下转义。
command > /dev/null 2>&1
不在屏幕上显示输出结果
和错误
。/dev/null 是一个特殊文件,写入到它的内容都会被丢弃,从该文件读取内容,什么也读不到。
ps -ef | grep memtester | grep -v grep | cut -c 9-16 | xargs kill -9
# a.sh
a()
{
return 1
}
if ! a ; then
echo "111"
fi
$ ./a.sh
111
# shift.sh
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#"
shift
done
$./shift.sh 1 2 3 4
第一个参数为: 1 参数个数为: 4
第一个参数为: 2 参数个数为: 3
第一个参数为: 3 参数个数为: 2
第一个参数为: 4 参数个数为: 1
# shift1.sh
sum=0
until [ $# -eq 0 ]
do
sum=`expr $sum + $1`
shift
done
echo "sum is: $sum"
$./shift1.sh 10 20 15
结果显示:45
basename /usr/local/nginx/conf/nginx.conf
nginx.conf
basename -s .conf /usr/local/nginx/conf/nginx.conf
nginx
dirname //
/
dirname /a/b/
/a
dirname a
.
dirname a/b
a
realpath $path : 返回$path的绝对路径,路径不存在会报错,文件不存在不会报错
declare与let:let命令和双小括号 (( )) 的用法是类似的,它们都是用来对整数进行运算,不能对小数(浮点数)或字符串运算。
整型运算如上同如下。
test:用于检查某个条件是否成立,它可以进行数值、字符、文件三个方面的测试
1.2 函数:shell脚本传递的参数中包含空格,应使用单引号或双引号将该参数括起来,以便于脚本将这个参数作为整体来接收。if [ -n str1 ] 当字符串的长度大于0时为真(字符串非空)
1.3 运算:算术、关系、布尔、逻辑、字符串、文件运算
算术:
关系:
布尔:
逻辑:
文件测试运算:
1.4 流程控制:if、for、while、case
if:
for:
while:
until:
case:
break与continue:
2.ssh_tool:sed -i ‘s/\r//g’ 文件(删除从txt复制来代码的换行符)
#!/usr/bin/expect
# b文件,llength等是expect中专属的,和ftp那些命令一样
# obmc-server:~$ whereis expect
# expect: /usr/bin/expect /usr/share/man/man1/expect.1.gz
puts "$argv0"
set arg_leng [llength $argv]
puts "$arg_leng"
set argv_0 [lindex $argv 0]
puts "$argv_0"
# @obmc-server:~/test$ ./b w
# ./b
# 1
# w
#!/usr/bin/expect
# 如上一行必须加且必须在第一行
if { [llength $argv] < 1} {
puts "Usage:"
puts "$argv0 raspberr ttyUSBx <pi2 0>" # ssh-tool.sh pi2 0
puts "$argv0 raspberr <pi1> <pi2> <pi3>" # ssh-tool.sh pi1
puts "$argv0 project_name <hollywood> <s3ip-bmc> <s3ip-bsp>" # ssh-tool.sh hollywood
# puts "$argv0 raspberrNUM ttyUSBx [force]" # ssh-tool.sh pi1 0 force
# puts "force if other used tty will kill process,杀串口进程"
exit 1
}
set arg_leng [llength $argv ]
set argv_0 [lindex $argv 0]
set ttyUSBx [lindex $argv 1]
# set force [lindex $argv 2]
set timeout 20
# set pi3_ip [exec sh -c {curl -s http://10.75.92.228:8080/api/help | python -m json.tool |grep -i "pi3" |cut -d '"' -f 4}]
set pi3_ip 10.75.159.104
set local_file ./tmp/deploy/images/obmc-cl/flash-obmc-cl
set passwderror 0
#11111111111111111111111111111111111111111111111111111111111111111111111111
if { $argv_0 == "pi1" } {
set passwd 123456
spawn ssh pi@$pi1_ip
}
if { $argv_0 == "pi2" } {
set passwd 123456
spawn ssh pi@$pi2_ip
}
if { $argv_0 == "pi3" } {
set passwd 123456
spawn ssh pi@$pi3_ip
}
if { $argv_0 == "hollywood" } {
set passwd 0penBmc
spawn ssh-keygen -f "/home_a/yu/.ssh/known_hosts" -R $hollywood_ip
spawn ssh root@$hollywood_ip
}
if { $argv_0 == "docker" } {
set passwd 1
spawn ssh cit@10.75.159.16
expect {
"*yes/no*" {
send "yes\r"
exp_continue
}
"*assword:*" {
if { $passwderror == 1 } {
puts "passwd is error"
exit 2
}
set timeout 1000
set passwderror 1
send "$passwd\r"
sleep 0.2
send "sudo su\r"
sleep 0.2
send "$passwd\r"
sleep 0.2
send "docker exec -it 16d93b0d2026 bash\r"
sleep 0.2
send "zsh\r"
sleep 0.2
send "ls\r"
sleep 0.2
send "cd\r"
interact
}
}
}
#11111111111111111111111111111111111111111111111111111111111111111111111111
expect {
"*yes/no*" {
send "yes\r"
exp_continue # 该项被匹配后,还能继续匹配该expect判断语句内的其他项
}
"*assword:*" {
if { $passwderror == 1 } {
puts "passwd is error"
exit 2
}
set timeout 1000
set passwderror 1
send "$passwd\r"
if { $arg_leng == 1} {
interact # 执行完成后保持交互状态,把控制权交给控制台,这个时候便可以手动操作。
# 如果没有该命令,命令完成后即退出。
}
if { $arg_leng == 2} {
exp_continue
}
}
"*pi@raspberrypi*" {
send " picocom -b 115200 /dev/ttyUSB$ttyUSBx\r"
exp_continue
}
"*FATAL: cannot lock*" {
# if { $force == "force" } {
# puts "you can kill process and try again"
# exit 1
# }
send " ps -ef |grep -i ttyUSB$ttyUSBx\r "
interact
}
"*FATAL: cannot open*" {
puts "!!! ######################################## !!!"
puts "!!!no ttyUSB$ttyUSBx"
exit 1
}
"*Terminal ready*" {
interact
}
}
3.build_bmc:To go back to default recipes: devtool reset linux-aspeed , devtool reset u-boot
#!/bin/bash
# downloads() {
# echo "buildpath: [$buildpath]"
# build_exist=$(grep "DL_DIR" $buildpath/conf/local.conf)
# echo "buildexist: [$build_exist]"
# if [ ! -n "$build_exist" ]; then
# echo "DL_DIR ?= \"/home_a/y/usr/local/downloads\"" >> "conf/local.conf"
# fi
# }
# buildplatform() {
# source openbmc-init-build-env meta-huaqin/meta-$1 build-$1
# buildpath=$(pwd)
# downloads
# bitbake $1-image
# rm -rf conf/local.conf
# }
usage() {
echo "Usage: build an openbmc image"
echo " $(basename $0) <platform>"
echo " $(basename $0) <platform> <feature>"
echo " $(basename $0) <platform> <clean>"
echo " $(basename $0) <platform> <clean> <feature>"
echo
echo "Examples:"
echo " $(basename $0) kestrel"
echo " $(basename $0) kestrel ipmid"
echo " $(basename $0) kestrel clean"
echo " $(basename $0) kestrel clean ipmid"
}
# if [ $# -eq 1 ]; then
# buildplatform $1
if [ $# -eq 1 ]; then
source ./setup $1;
echo "DL_DIR ?= \"/home_a/y/usr/local/downloads_ocp\"" >> "conf/local.conf" # openbmc-hollywood-master/build/conf/local.conf 或 meta-huaqin/meta-xs9880-8c/conf/local.conf.sample
bitbake obmc-phosphor-image
elif [ $# -ge 2 ]; then
case $2 in
"clean")
source ./setup $1;
echo "DL_DIR ?= \"/home_a/y/usr/local/downloads_ocp\"" >> "conf/local.conf"
bitbake obmc-phosphor-image -c cleanall obmc-phosphor-image
;;
"u-boot")
# source openbmc-init-build-env meta-huaqin/meta-$1 build-$1 && buildpath=$(pwd); downloads; bitbake u-boot
;;
"linux-aspeed")
# source openbmc-init-build-env meta-huaqin/meta-$1 build-$1 && buildpath=$(pwd); downloads; bitbake linux-aspeed
;;
*)
source openbmc-init-build-env meta-huaqin/meta-$1 build-$1 && buildpath=$(pwd); downloads; bitbake $2
;;
esac
else
usage
fi
exit 0
# build目录下获取源码:devtool modify linux-aspeed ,devtool modify u-boot
# This will create local Linux package under /workspace/sources/linux-aspeed for development
chmod 777 /home_a/y/app/bin/(usr/local/bin/)build_bmc
~$ vi .bash_profile
export PATH=/home_a/y/app/bin:$PATH
~$ vi .bashrc
alias gr='grep -nr'
4.环境变量:用bash调用脚本的时候会创建一个和自己一模一样的shell子进程执行这个外部命令。这个子进程中设置了自己的运行的环境变量,此时父进程的环境变量并没有改变。bash test.sh == ./test.sh。
用source来执行脚本的时候,不会创建子进程,而是在父进程
中直接执行,所以当需要程序修改当前shell本身的环境变量的时候,用source命令。source test.sh == . test.sh
。如下记住ebe从大到小。
上面就是改变linux的env的三种方法,每个用户env都不一样
,env中HOME为用户主目录。
export在命令行单独输入是临时的(export…,env可查到多出了刚export的,但用户登出再登录,env查看没有刚export的)。但在.bash_profile中都含有export,用户一登录就执行.bash_profile
,所以env中含有这些环境变量,这样export可视为永久。
所有可执行程序
都要PATH指定,如ls,pwd(也是可执行程序)不加./(./是在当前目录执行),因为在冒号分隔(冒号不是连接)的几个目录下找。sqlplus命令行命令在/oracle/bin中。
ls这个可执行程序就是在bin目录下,上面PATH已指定。如下若未改为英文显示:未找到命令(中文)。
如下必须在用户主目录/oracle,才能vi .bash_profile。
如下对所有用户有效。
/etc/profile 是文件(里面有不建议在这文件里修改的英文说明), /etc/profile.d/ 是目录(如下新建.sh文件创建全局环境变量)。
如下在sss.sh中写入下行。/etc/profile这个文件中有这么一段shell:for i in /etc/profile.d/*.sh;,会在每次启动时自动加载profile.d目录中每个配置。
不想要什么变量直接删除 /etc/profile.d/ 下对应的shell 脚本
即可,当用户重新登录shell如下或source /etc/profile 时会触发。
5.scp_image:不用管STRING1
#!/usr/bin/expect
if { [llength $argv] < 2} {
puts "Usage:"
puts "$argv0 <Image path> IP"
puts "$argv0 <Image path> IP <path>"
exit 1
}
set timeout 20
set Local_File [lindex $argv 0]
set IP [lindex $argv 1]
set STRING 0
spawn ssh-keygen -f "/home_a/y/.ssh/known_hosts" -R $IP
proc myscpfunc { STRING1 } {
set passwd 0penBmc
set passwderror 0
expect {
"*assword:*" {
if { $passwderror == 1 } {
puts "passwd is error"
exit 2
}
set timeout 1000
set passwderror 1
send "$passwd\r"
exp_continue
}
"yes/no" {
send "yes\r"
exp_continue
}
timeout {
puts "connect is timeout"
exit 3
}
}
}
if { [llength $argv] == 2} {
if {[regexp -nocase "obmc-phosphor-image" $Local_File]} {
spawn scp $Local_File root@$IP:/tmp/images
myscpfunc $STRING
spawn scp /home_a/y/bak/bmc_upgrade root@$IP:~/
myscpfunc $STRING
} else {
spawn scp $Local_File /home_a/y/bak/bmc_upgrade root@$IP:~/
myscpfunc $STRING
}
}
if { [llength $argv] == 3} {
set path [lindex $argv 2]
spawn scp $Local_File root@$IP:$path
myscpfunc $STRING
}
6.bmc_upgrade:断电重启才从主启,当前永远mtd4
if [ $# -lt 1 ];then
echo "Usage: `basename $0`+<1;2;all>"
echo "1 : flash0"
echo "2 : flash0ro"
echo "all : flash0 & flash0ro"
echo "ocp : update ocpbmc image"
exit 255
fi
cat /proc/mtd |grep -i "flash0\""
cat /proc/mtd |grep -i "flash0ro"
F0_string=$(cat /proc/mtd |grep -i flash0\" |cut -b 1-4)
F1_string=$(cat /proc/mtd |grep -i flash0ro |cut -b 1-4)
if [ "$F1_string" = "" ]; then
F1_string=$(cat /proc/mtd |grep -i flash1 |cut -b 1-4)
fi
if [ $1 == "1" ]; then
source /usr/local/bin/openbmc-utils.sh
echo "Update /dev/$F0_string"
flashcp ./flash-* /dev/$F0_string
elif [ $1 == "2" ]; then
source /usr/local/bin/openbmc-utils.sh
echo "Update /dev/$F1_string"
flashcp ./flash-* /dev/$F1_string
elif [ $1 == "all" ]; then
source /usr/local/bin/openbmc-utils.sh
echo "Update /dev/$F0_string & /dev/$F1_string"
echo "First : Update /dev/$F0_string"
flashcp ./flash-* /dev/$F0_string
echo "Second : Update /dev/$F1_string"
flashcp ./flash-* /dev/$F1_string
elif [ $1 == "ocp" ]; then
Image_ID=$(ls /tmp/images/)
if [ ${#Image_ID} -eq 8 ];then
echo "IMAGE ID = ${Image_ID}"
else
echo "IMAGE ID = ${Image_ID}"
echo "Error-----multiple image"
exit 255
fi
echo "busctl set-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/$Image_ID xyz.openbmc_project.Software.Activation RequestedActivation s xyz.openbmc_project.Software.Activation.RequestedActivations.Active"
busctl set-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/$Image_ID xyz.openbmc_project.Software.Activation RequestedActivation s xyz.openbmc_project.Software.Activation.RequestedActivations.Active
sleep 3
echo "busctl get-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/$Image_ID xyz.openbmc_project.Software.Activation Activation"
busctl get-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/$Image_ID xyz.openbmc_project.Software.Activation Activation
sleep 1
fi
if [ $? == "0" ];then
echo "Update Over"
echo "reboot now !!!!"
reboot
else
echo "Update fail !!!!"
fi
7.自动升级bmc:AC ON物理上电
#!/bin/sh
#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
BMC_VERSION=/var/log/automatic_upgrade/version/bmc_version #主备版本都和这个比较,而不是主备互相比较
BMC_FW=/var/log/automatic_upgrade/fw/flash-xs9880-8c
BMC_WTD2_COUNT=/var/log/wtd_count
BMC_FW_UPDATE_COUNT=/var/log/bmc_update_count
FW_UPDATE_TIMES=8
check_file_ok() {
if [ ! -f "$BMC_WTD2_COUNT" ]; then #这行if是:假如不存在文件
echo 0 > $BMC_WTD2_COUNT #创建文件并写0
fi
if [ ! -f "$BMC_FW_UPDATE_COUNT" ]; then
echo 0 > $BMC_FW_UPDATE_COUNT
fi
if [ ! -f "$BMC_VERSION" ] || [ ! -f "$BMC_FW" ]; then
echo "$BMC_VERSION or $BMC_FW file does not exist"
exit 255
fi
}
check_fw_update_count() {
bmc_fw_update_cont=$(cat "$BMC_FW_UPDATE_COUNT")
if [ "$FW_UPDATE_TIMES" -lt "$bmc_fw_update_cont" ]; then
logger -p user.err "$0 update bmc times exceeded"
exit 255
fi
}
check_wtd2_count() {
if [ "$wdt2_timeout_count" -eq 0 ]; then
echo 0 > $BMC_WTD2_COUNT
fi
}
#11111111111111111111111111111111111111111111111111111111111111111111111111111
update_bmc_fw() {
if [ "$1" = "current" ]; then
flashcp $BMC_FW /dev/mtd4
elif [ "$1" = "other" ]; then
flashcp $BMC_FW /dev/mtd9
fi
}
change_bmc_boot() {
if [ "Master"x = "$bmc_boot"x ]; then
bmc_boot_info.sh reset slave
else
bmc_boot_info.sh reset master
fi
}
get_bmc_version() {
if [ "$1" = "other" ]; then
bmc_version=$(version_dump --pingpong | awk -F ": " '{print $2}')
elif [ "$1" = "current" ]; then
bmc_version=$(version_dump bmc | awk -F ": " '{print $2}')
fi
echo "$bmc_version"
}
#1111111111111111111111111111111111111111111111111111111111111111111111111111111
update_bmc_fw_update_count() {
index=$(cat "$BMC_FW_UPDATE_COUNT")
index=$((index+1))
echo $index > $BMC_FW_UPDATE_COUNT
}
update_wdt2_timeout_count() {
echo "$wdt2_timeout_count" > $BMC_WTD2_COUNT
}
clean_bmc_fw_update_count() {
echo 0 > $BMC_FW_UPDATE_COUNT
}
#111111111111111111111111111111111111111111111111111111111111111111111111111111
main() {
check_file_ok
bmc_boot_info=$(bmc_boot_info.sh)
bmc_boot=$(echo $bmc_boot_info |awk -F " " '{print $10}')
wdt2_timeout_count=$(echo $bmc_boot_info |awk -F " " '{print $4}')
bmc_base_version=$(cat "$BMC_VERSION")
bmc_wtd2_count=$(cat "$BMC_WTD2_COUNT")
current_version=$(get_bmc_version current)
other_version=$(get_bmc_version other)
check_wtd2_count
check_fw_update_count
echo "$current_version"
echo "$other_version"
echo "$bmc_wtd2_count"
echo "$wdt2_timeout_count"
if [ "$bmc_wtd2_count"x = "$wdt2_timeout_count"x ]; then # N(No) WTD没有增加
if [ "$bmc_base_version"x = "$current_version"x ]; then # 文件版本和当前版本一致
if [ "$bmc_base_version"x = "$other_version"x ]; then # 文件版本和对面版本一致
echo "all same"
clean_bmc_fw_update_count
else # 文件版本和当前版本一致,但不和对面版本一致 【只有非当前版本一致】
echo "only other not same"
update_bmc_fw_update_count
update_bmc_fw other
fi
else # 文件版本和当前版本不一致
if [ "$bmc_base_version"x = "$other_version"x ]; then # 【只有当前BMC版本不一致】
echo "only current not same"
change_bmc_boot
else # 【两块BMC版本都不一致】
echo "all not same"
update_bmc_fw_update_count
update_bmc_fw other
change_bmc_boot
fi
fi
else #Y WTD增加了
update_wdt2_timeout_count
if [ "$bmc_base_version"x = "$current_version"x ]; then #【当前BMC版本一致】
echo "current same"
update_bmc_fw_update_count
update_bmc_fw other
else # 【当前BMC版本不一致】
echo "current not same"
update_bmc_fw_update_count
update_bmc_fw other
change_bmc_boot
fi
fi
}
main