文章目录
变量
变量的使用
$varName
或
${varName}
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变
myUrl="http://www.google.com"
readonly myUrl
删除变量
unset varName
shell字符串
单引号
str=‘this is a string’
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号
str=“Hello, I know you are “$your_name”! \n”
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串
使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
#使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
获取字符串长度
${#str}
string="abcd"
echo ${#string}
提取子字符串
${str:Lindex:Hindex}
#字符串第一个字符的索引为0
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找子字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
shell数组
定义数组
数组名=(值1 值2 … 值n) #空格分隔
或
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen #可以不使用连续的下标,而且下标的范围没有限制
读取数组
${数组名[下标]}
数组操作
#获取数组所有元素
${array_name[*]}
# 或者
${array_name[@]}
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
shell的特殊变量
参数处理 | 说明 |
---|---|
$0 | 当前脚本的文件名,或函数的名字 |
$n | 传递给脚本或函数的参数,其中n=1,2,…,n |
$# | 传递给脚本或函数的参数个数 |
$* | 传递给脚本或函数的所有参数 |
$@ | 传递给脚本或函数的所有参数 |
$? | 最后命令的退出状态。0表示没有错误,其他任何值表明有错误 |
$$ | 当前shell进程的ID |
$! | 后台运行的最后一个进程的ID号 |
$- | 显示Shell使用的当前选项,与set命令功能相同 |
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号" “包含时,都以”$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。但当被双引号" “包含时,$* 会将所有的参数作为一个整体,以”$1 $2 … n " 的 形 式 输 出 所 有 参 数 ; n"的形式输出所有参数; n"的形式输出所有参数;@会将各个参数分开,以"$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。
shell特殊指令
which
Linux which命令用于查找文件,which指令会在环境变量$PATH设置的目录里查找符合条件的文件
which [文件…]
参数:
- -n<文件名长度> 指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名
- -p<文件名长度> 与-n参数相同,但此处的<文件名长度>包括了文件的路径
- -w 指定输出时栏位的宽度
- -V 显示版本信息
whereis
Linux whereis命令用于查找文件,该指令会在特定目录中查找符合条件的文件,这些文件应属于原始代码、二进制文件,或是帮助文件,该指令只能用于查找二进制文件、源代码文件和man手册页,一般文件的定位需使用locate命令
whereis [-bfmsu][-B <目录>…][-M <目录>…][-S <目录>…][文件…]
参数:
- -b 只查找二进制文件
- -B<目录> 只在设置的目录下查找二进制文件
- -f 不显示文件名前的路径名称
- -m 只查找说明文件
- -M<目录> 只在设置的目录下查找说明文件
- -s 只查找原始代码文件
- -S<目录> 只在设置的目录下查找原始代码文件
- -u 查找不包含指定类型的文件
who
whoami
Shell各种括号使用
()
- 命令组。括号中的命令将新打开一个子shell顺序执行,所有括号中的变量不能被括号外的脚本使用,括号中的多个命令之间用分号";"分隔,最后一个命令可以没有分号。
- 命令替换。等同于cmd,shell扫描一遍命令行,如果发现$(cmd)结构,便将$(cmd)中的cmd执行,得到标准输出,再将此输出放到原来命令,如 for i in $(ls)。有些shell不支持,如tcsh。
- 用于初始化数组。如:array=(a b c d)
(())
- 整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。
- 只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。用作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)。
- 单纯用(( ))也可重定义变量值,比如a=5; ((a++))可将 $a重定义为6。
- 常用于算术运算比较,双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0…4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。
- 如果要把双小括号的运算结果返回给shell中的变量则需要在双小括号前面加入$。
[]
- bash 的内部命令,[ 和test是等同的。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。并且根据比较的结果来返回一个退出状态码。
- test和[ ]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq、-gt这种形式。无论是字符串比较还是整数比较都不支持> 和 <比较。如果实在想用,对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab < bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a和-o表示。
- 字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。
- 在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。
[[]]
- [[是bash 程序语言的关键字。[[ ]]结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
- 支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]]中匹配字符串或通配符,不需要引号。
- 使用[[ … ]]条件判断结构,能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
- bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
{}
- 大括号拓展。(通配(globbing))将对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(…)分割的顺序文件列表起拓展作用,如:touch {a…d}.txt 结果为a.txt b.txt c.txt d.txt。
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
- 代码块,又被称为内部组,这个结构实际上创建了一个匿名函数。与小括号中的命令不同,大括号内的命令不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,最后一个也必须有分号。{}的第一个命令和左括号之间必须要有一个空格。
符号$后的括号
- ${a} 变量a的值, 在不引起歧义的情况下可以省略大括号
- $(cmd) 命令替换,和`cmd`效果相同,结果为shell命令cmd的输,过某些Shell版本不支持$()形式的命令替换, 如tcsh
- $((expression)) 和`exprexpression`效果相同, 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算
Shell的${}与##、%%、//的使用
假设我们定义了一个变量为:
file=/dir1/dir2/dir3/my.file.txt
删除用法
- ${file#*/}:删掉第一个 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
- ${file##*/}:删掉最后一个 / 及其左边的字符串:my.file.txt
- ${file#*.}:删掉第一个 . 及其左边的字符串:file.txt
- ${file##*.}:删掉最后一个 . 及其左边的字符串:txt
- ${file%/*}:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
- ${file%%/*}:删掉第一个 / 及其右边的字符串:(空值)
- ${file%.*}:删掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
- ${file%%.*}:删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
#是 去掉左边(键盘上#在 $ 的左边)
%是去掉右边(键盘上% 在$ 的右边)
单一符号是最小匹配;两个符号是最大匹配
替换用法
- ${file/dir/path}:将第一个dir 替换为path:/path1/dir2/dir3/my.file.txt
- ${file//dir/path}:将全部dir 替换为path:/path1/path2/path3/my.file.txt
提取用法
- ${file:0:5}:提取最左边的5 个字节:/dir1
- ${file:5:5}:提取第5 个字节右边的连续5个字节:/dir2
计算长度
- ${#file}: 可得到27,/dir1/dir2/dir3/my.file.txt 是27个字节
shell信号
发送信号(kill)
kill 命令发送信号给进程
命令格式:
kill [-s sigspec | -n signum | -sigspec] pid | jobspec
kill -l [sigspec]
- -s # 信号名称
- -n # 信号编号
- -l # 打印编号 1-31 信号名称
示例:
给一个进程发送终止信号:
kill -s SIGTERM pid
kill -n 15 pid
kill -15 pid
kill -TREM pid
接收信号(trap)
trap 命令定义 shell 在处理程序运行时接受信号,来做相应的处理
命令格式:trap [-lp] [[arg] signal_spec …]
- -l 打印编号 1-64 编号信号名称
- arg 捕获信号后执行的命令或者函数
- signal_spec 信号名或编号
一般捕捉信号后,做以下几个行动:
- 清除临时文件
- 忽略该信号
- 询问用户是否终止脚本执行
示例:
- 按 CTRL+C 不退出循环
trap "" 2 # 不指定 arg 就不做任何操作,后面也可以写多个信号,以空格分隔
- 循环打印数字,按 CTRL+C 退出,并打印退出提示
trap "echo 'exit...';exit" 2
- 让用户选择是否终止循环
#!/bin/bash
trap "func" 2
func() {
read -p "Terminate the process? (Y/N): " input
if [ $input == "Y" ]; then
exit
fi
}
几种特殊的替换结构
${var:-string},${var:+string},${var:=string},${var:?string}
- ${var:-string}:若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string}。
- ${var:=string}:若var为空时,用string替换${var:=string}的同时,把string赋给变量var,否则变量var不为空时,则用变量var的值来替换${var:=string};${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。
- ${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。
- ${var:?string}替换规则为:若变量var不为空,则用变量var的值来替换${var:?string};若变量var为空,则把string输出到标准错误中,并从脚本中退出(可利用此特性来检查是否设置了变量的值)。
- 补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出
${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
- ${variable%pattern},shell在variable中查找,是否给定的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最短的匹配模式
- ${variable%%pattern},shell在variable中查找,是否给定的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
- ${variable#pattern} ,shell在variable中查找,是否给定的模式pattern开始,如果是,就从命令行把variable中的内容去掉左边最短的匹配模式
- ${variable##pattern},shell在variable中查找,是否给定的模式pattern开始,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
- 这四种模式中都不会改变variable的值,其中,只有在pattern中使用了*匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,*表示零个或多个任意字符,?表示仅与一个任意字符匹配,[…]表示匹配中括号里面的字符,[!..]表示不匹配中括号里面的字符
- # 是去掉左边,% 是去掉右边,#%中的单一符号是最小匹配,两个相同符号是最大匹配
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}
- ${var:num},这种模式时,shell在var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如${var: -2}、${var:1-3}或${var:(-2)}
- ${var:num1:num2},num1是位置,num2是长度。表示从$var字符串的第$num1个位置开始提取长度为$num2的子串。不能为负数
- ${var/pattern1/pattern2}表示将var字符串的第一个匹配的pattern1替换为另一个pattern2
- ${var//pattern1/pattern2}表示将var字符串中的所有能匹配的pattern1替换为另一个pattern2
[root@centos ~]# var=/home/centos
[root@centos ~]# echo $var
/home/centos
[root@centos ~]# echo ${var:5}
/centos
[root@centos ~]# echo ${var: -6}
centos
[root@centos ~]# echo ${var:(-6)}
centos
[root@centos ~]# echo ${var:1:4}
home
[root@centos ~]# echo ${var/o/h}
/hhme/centos
[root@centos ~]# echo ${var//o/h}
运算符
类型 | 运算符 |
---|---|
算术运算符 | +(加) -(减) *(乘) /(除) %(取余) =(赋值) ==(相等) !=(不相等) |
关系运算符 | -eq(等于) -ne(不等于) -gt(大于) -lt(小于) -ge(大于等于) -le(小于等于) |
正则匹配 | =~(判断其左则参数是否符合右则正则要求) |
布尔运算符 | !(非运算) -o(或运算) -a(与运算) |
逻辑运算符 | &&(逻辑与) ||(逻辑或) |
字符串运算符 | =(等于) !=(不等于) -z(长度是否为零) -n(长度是否不为零) $(是否为空) |
文件测试运算符 | -b -c -d -f -g -k -p -u -r -w -x -s -e |
printf命令
- %s %c %d %f都是格式替代符
- %-10s 指一个宽度为10个字符(-表示左对齐,否则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
- %-4.2f 指格式化为小数,其中.2指保留2位小数。
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
序列 | 说明 |
---|---|
\a | 警告字符,通常为ASCII的BEL字符 |
\b | 后退 |
\c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f | 换页(formfeed) |
\n | 换行 |
\r | 回车(Carriage return) |
\t | 水平制表符 |
\v | 垂直制表符 |
\ | 一个字面上的反斜杠字符 |
\ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
\0ddd | 表示1到3位的八进制值字符 |
流程控制
break continue
if
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for
for var in item1 item2 ... itemN
do
command1
...
commandN
done
while
while condition
do
command
done
until
until condition
do
command
done
case
case 值 in
模式1)
command1
...
commandN
;;
模式2)
command1
...
commandN
;;
esac
shell函数
[ function ] funname [()]
{
action;
[return int;]
}
输入输出重定向
文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file |
command < file | 将输入重定向到 file |
command >> file | 将输出以追加的方式重定向到 file |
n > file | 将文件描述符为 n 的文件重定向到 file |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file |
n >& m | 将输出文件 m 和 n 合并 |
n <& m | 将输入文件 m 和 n 合并 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
如果希望将 stdout 和 stderr 合并后重定向到 file
$ command > file 2>&1
如果希望对 stdin 和 stdout 都重定向
$ command < file1 >file2
shell文件包含
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
test命令详解
test命令用法。功能:检查文件和比较值
如果条件为真,则返回一个 0 值。如果表达式不为真,则返回一个大于 0 的值
test expression
[ expression ] 其中左方括号和右方括号,都要留一个空格,如果报错,则改为[[ expression ]]
判断表达式
示例 | 说明 |
---|---|
if test expr | 表达式为真 |
if test !expr | 表达式为假 |
test expr1 –a expr2 | 两个表达式都为真 |
test expr1 –o expr2 | 两个表达式有一个为真 |
判断字符串
示例 | 说明 |
---|---|
test –n str | 字符串的长度非零 |
test –z str | 字符串的长度为零 |
test str1 = str2 | 字符串相等 |
test str1 != str2 | 字符串不等 |
判断整数
示例 | 说明 |
---|---|
test int1 –eq int2 | 整数相等 |
test int1 –ge int2 | 整数1大于等于整数2 |
test int1 –gt int2 | 整数1大于整数2 |
test int1 –le int2 | 整数1小于等于整数2 |
test int1 –lt int2 | 整数1小于整数2 |
test int1 –ne int2 | 整数1不等于整数2 |
判断文件
示例 | 说明 |
---|---|
test File1 –ef File2 | 两个文件具有同样的设备号和i结点号 |
test File1 –nt File2 | 文件1比文件2 新 |
test File1 –ot File2 | 文件1比文件2 旧 |
test –b File | 文件存在并且是块设备文件 |
test –c File | 文件存在并且是字符设备文件 |
test –d File | 文件存在并且是目录 |
test –e File | 文件存在 |
test –f File | 文件存在并且是正规文件 |
test –g File | 文件存在并且是设置了组ID |
test –G File | 文件存在并且属于有效组ID |
test –h File | 文件存在并且是一个符号链接(同-L) |
test –k File | 文件存在并且设置了sticky位 |
test –b File | 文件存在并且是块设备文件 |
test –L File | 文件存在并且是一个符号链接(同-h) |
test –o File | 文件存在并且属于有效用户ID |
test –p File | 文件存在并且是一个命名管道 |
test –r File | 文件存在并且可读 |
test –s File | 文件存在并且是一个套接字 |
test –t FD | 文件描述符是在一个终端打开的 |
test –u File | 文件存在并且设置了它的set-user-id位 |
test –w File | 文件存在并且可写 |
test –x File | 文件存在并且可执行 |
read命令
read -p “string” -n 6 -t 5 -s password
- -p 输入提示文字
- -n 输入字符长度限制
- -t 输入限时
- -s 隐藏输入内容
字符串分割成数组
OLD_IFS="$IFS" #OLD_IFS用于备份默认的分隔符
IFS="," #IFS存储分隔符
array=($string) #($string)将字符串string分隔成数组
shell调试
静态检查语法错误
sh -n 脚本名;
动态运行逻辑
- sh -c ‘语句’ =>运行一小句
- sh -v 脚本名 =>运行脚本,输出运行的原始语句
- sh -x 脚本名 =>运行脚本,输出运行的语句,并替换符号变量
使用方式:
1)在命令行输入:$sh -x script.sh
2)在脚本开头提供参数:#!/bin/sh -x
3)在脚本中用set命令启用 或 禁用:其中set -x表示启用,set +x表示禁用
调试输出:
1)在标准输出设备stdin上输出+开始的shell脚本语句
2)多个+的情况,表示改行被调用的层次
使用工具调试
bashdb
常用shell命令
find
示例
#!/bin/bash
echo "test ERROR led bug for loop"
trap 2
trap "echo 'exit...';exit" 11
if test ! -f "testLoop.txt"
then
touch "testLoop.txt"
fi
echo "testLoop start" > testLoop.txt
if test -e "build/FactoryTestRC10"
then
filePath="build/FactoryTestRC10"
elif test -e "FactoryTestRC10"
then
filePath="FactoryTestRC10"
else
echo "Can't fine file" >> testLoop.txt
fi
echo "file path:${filePath}" >> testLoop.txt
if test ! -x ${filePath}
then
chmod +x ${filePath}
fi
loop=0
while true
do
loop=`expr ${loop} + 1`
echo "loop=${loop}" >> testLoop.txt
time=$(date)
echo ${time} >> testLoop.txt
${filePath} >> testLoop.txt
errorValue=`cat /sys/class/gpio/gpio332/value`
if [[ ${errorValue} = 0 ]]
then
echo "ERROR LED value:" >> testLoop.txt
echo ${errorValue} >> testLoop.txt
echo "Error LED is light"
exit 0
fi
# sleep 10
done
读取文件当个字节,然后写入到某个设备中,如网络设备的eeprom
#!/bin/bash
#bin file format value
file_format="0xA5"
#ethernet dev name
dev_name=$1
#ethernet bin name
file_name=$2
#cmd magic name
magic_name=$3
trap 2
trap "echo 'exit...';exit" 11
#help indicated
print_help()
{
echo -e "Usage: sudo ./enthernet_eeprom.sh DEVNAME FILENAME MAGIC"
}
#check param nums
if test $# != 3
then
echo invail prama : $@ total nums:$#
print_help
fi
#check ethernet dev_name whether exist
exist_flag=0
ethernet_array=`ifconfig | grep Ethernet | cut -d ' ' -f 1`
ethernet_num=${#ethernet_array[@]}
for var in ${ethernet_array}
do
if [ "${dev_name}" == "${var}" ]
then
exist_flag=1
fi
done
if test ${exist_flag} -eq 0
then
echo "The device name of input do not exist"
exit
fi
#get bin file info and check eeprom sizes
file_size=`wc -c ${file_name} | awk '{print $1}'`
dev_eeprom_size=`sudo ethtool -e ${dev_name} | grep : | wc -l`
dev_eeprom_size=`expr ${dev_eeprom_size} \* 16`
if test ${file_size} -gt ${dev_eeprom_size}
then
echo "The file siezs:${file_size} bigger than eeprom size:${dev_eeprom_size}"
exit
fi
#get byte from a file with hex format output and check first byte
byte=`head -c 1 ${file_name} | hexdump -e '1/1 "%02X"'`
byte_value=0x${byte}
if test ${byte_value} != ${file_format}
then
echo "The file format error"
exit
fi
#write the bin file to eeprom one by one byte
for((loop=1;loop<=${file_size};loop++))
do
#get byte form file
byte=`head -c ${loop} ${file_name} | tail -c 1 | hexdump -e '1/1 "%02X"'`
byte_value=0x${byte}
offset_ops=`expr $loop - 1`
`sudo ethtool -E ${dev_name} magic ${magic_name} offset ${offset_ops} value ${byte_value}`
if test $? -ne 0
then
echo "Failed to write EEPROM at offset:${offset_ops},val:${byte_value}"
fi
done