最近负责移植固件升级
功能,发现原来的升级脚本将固件的路径名
和文件名
不做区分,导致脚本必须跟固件在同一路径下才能正确调用,殊为不便。
上代码:
sudo mkdir -p /lib/firmware/F260/
sudo cp $1 /lib/firmware/F260/
echo burn $1 to $2 ...
sudo echo F260/$1 > /sys/class/misc/PCIE_SubFpga1/d_${2}_update
脚本命令行第一个参数$1
就是固件的路径名,$2
是器件名(表明FPGA还是DSP)。
脚本的问题是,最后一行F260/$1
默认$1
是文件名,但如果固件跟脚本不在同一目录,则$1
必然携带目录名,导致Linux下载固件失败。
从路径名提取出文件名,就是用/
做分隔符,对路径名执行split
操作,获得token
数组,数组最后一个就是文件名。
为了减少sed/awk等进程启动,考虑直接用bash内置的read子命令
的-a选项
,以及bash的here strings
机制,实现这一目标。
bash默认的分隔符是空格,但用户可以自行修改,修改后的值存在$IFS
环境变量里
IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is
``''.
为了将路径名分割成一系列的目录名加(最后一个)文件名,我们就要将分隔符改成/
IFS='/'
注意 IFS
更改后尽快执行分割字符串操作,完了立即恢复IFS为空格,否则后续的cp
、rm
等文件系统操作都会因为文件路径被当作一系列token而报找不到文件!
IFS=' ' #分割字符串后立即恢复IFS配置!
split函数去哪儿找?read子命令来帮忙!
read子命令从标准输入读出一个个字符串token,然后绑定到一个个name环境变量。如果指定-a选项,则将所有token绑定到aname数组环境变量
read [-ers] [-a aname] [name ...]
One line is read from the standard input, or from the file descriptor fd supplied as an argument to the -u option, and the first word is assigned to the first name, the second word to the second name, and so on
-a aname
The words are assigned to sequential indices of the array variable aname, starting at 0. aname is unset before any new values are assigned. Other name arguments are ignored.
-r Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation.
-r选项表示将输入字符串中的\
当普通字符看待 ,一般可以不用管。
用户已经在命令行里填写好路径了,我们不需要再从标准输入读取字符串,于是需要重定向
标准输入
here strings
正是一种重定向
手段,将脚本的标准输入重定向到一个字符串
Here Strings
A variant of here documents, the format is:
<<
IFS='/'
read -ra LIST <<< "$1"
F=${LIST[-1]}
IFS=' ' #立即恢复IFS的默认值,否则会影响后面的命令!
sudo mkdir -p /lib/firmware/F260/
sudo cp $1 /lib/firmware/F260/
echo burn $F to $2 ...
sudo echo F260/$F > /sys/class/misc/PCIE_SubFpga1/d_${2}_update
dh@dh-desktop:~$ . test.sh /home/dh/7569_32/fpga_mainboard/F266_MBV1.bin firmware_fpga
burn F266_MBV1.bin to firmware_fpga ...
bash真的是一座宝库,值得反复探索。