1. boot_hook_init() {
  2. local hook="${1}_hook"
  3. export -n "PI_STACK_LIST=${PI_STACK_LIST:+$PI_STACK_LIST }$1"
  4. export -n "$hook="
  5.  
  6. echo $PI_STACK_LIST
  7.  
  8. }

1.export -n 和 local 和 export

进行一下实验:

test.sh

  1. export AA=11
  2. export -n BB=22
  3.  
  4. func()
  5. {
  6. local CC=33
  7. echo $CC
  8. }
  9.  
  10. echo $AA
  11. echo $BB
  12. echo $CC
  13.  
  14. func
    ./test2.sh

test2.sh

  1. echo "-----test2.sh-------"
  2. echo $AA
  3. echo $BB
  4. echo $CC

运行:

  1. 11
  2. 22
  3.  
  4. 33
  5. ------test2.sh------
  6. 11

得出结论:

local 只能在函数中定义变量,作用域为本函数

export 定义环境变量,作用域为本文件和其他文件

export -n 作用域为本文件

2.使用export 和 变量的一般定义

  1. VAR1=aaa
  2. $VAR1=bbb # n
  3. export $VAR=bbb # y
  4.  
  5. eval "echo \$$VAR" # --> echo $aaa ---> echo bbb

使用export可以先解引用,再定义。

3.

  1. local hook="${1}_hook${PI_HOOK_SPLICE:+_splice}"

当 PI_HOOK_SPLICE为空

${PI_HOOK_SPLICE:+_splice} 返回空

当PI_HOOK_SPLICE非空

${PI_HOOK_SPLICE:+_splice}返回_splice

相关知识

${var:-string} -- 如果${var}为空,用string替换${var:-string},否则使用${var}替换

${var:=string} -- 如果${var}为空,用string替换${var:=string},并且${var}赋值为string,否则同上

${var:+string} -- 如果${var}不为空,则用string替换${var:+string},否则同上(也就是空)

${var:?string} -- 如果${var}为空,报错并退出程序(命令。。。),否则${var}替换${var:?string}

4. 学习脚本

  1. boot_hook_init() {
  2. local hook="${1}_hook"
  3. export -n "PI_STACK_LIST=${PI_STACK_LIST:+$PI_STACK_LIST }$1" # PI_STACK_LIST 存储标签
  4. export -n "$hook=" # hook 存储函数名,保证hook为空
  5. }
  6.  
  7. boot_hook_add() {
  8. local hook="${1}_hook${PI_HOOK_SPLICE:+_splice}"
  9. local func="${2}"
  10.  
  11. [ -n "$func" ] && {
  12. local v; eval "v=\$$hook"
  13. export -n "$hook=${v:+$v }$func" # 将新的函数名添加到 hook
  14. }
  15. }
  16.  
  17. boot_hook_shift() {
  18. local hook="${1}_hook"
  19. local rvar="${2}"
  20.  
  21. local v; eval "v=\$$hook"
  22. [ -n "$v" ] && {
  23. local first="${v%% *}"
  24.                                            # 如果hook有多个函数名,则hook向后偏移
  25. [ "$v" != "${v#* }" ] && \
  26. export -n "$hook=${v#* }" || \
  27. export -n "$hook="
  28.  
  29. export -n "$rvar=$first" # 将第一个函数名返回
  30. return 0
  31. }
  32.  
  33. return 1
  34. }
  35.  
  36. boot_run_hook() {
  37. local hook="$1"
  38. local func
  39.  
  40. while boot_hook_shift "$hook" func; do
  41. local ran; eval "ran=\$PI_RAN_$func"
  42. [ -n "$ran" ] || { # 如果本函数从未执行过,则执行
  43. export -n "PI_RAN_$func=1"
  44. $func "$1" "$2"
  45. }
  46. done
  47. }

脚本使用

  1. . preinit.sh
  2.  
  3. boot_hook_init main1
  4. boot_hook_init main2
  5.  
  6. func1(){
  7. echo "func1"
  8. }
  9. func2(){
  10. echo "func2"
  11. }
  12. func3(){
  13. echo "func3"
  14. }
  15.  
  16. boot_hook_add main1 func1
  17. boot_hook_add main1 func2
  18. boot_hook_add main2 func3
  19. boot_run_hook main1
  20. boot_run_hook main2

openwrt——preinit.sh学习的更多相关文章

  1. 转:openwrt中luci学习笔记

    原文地址:openwrt中luci学习笔记 最近在学习OpenWrt,需要在OpenWrt的WEB界面增加内容,本文将讲述修改OpenWrt的过程和其中遇到的问题. 一.WEB界面开发         ...

  2. 【转】Android source build/envsetup.sh学习笔记

    原文网址:http://blog.csdn.net/mliubing2532/article/details/7567164 如果你只需要修改某一个模块的内容,但是却每次都要执行make, 最后等待很 ...

  3. CWMP开源代码研究2——easycwmp安装和学习

    声明:本文是对开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文所有笔记和代码可以到csdn下载:http://download.csdn.n ...

  4. Openwrt LuCI模块练习详细步骤

    前言 又到了成胖子^_^每周一博的时间了.最近在学习openwrt luci方面的知识,为了贯穿整个知识体系,练习题目为: 通过页面配置周期性地往/tmp/addtest文件写入内容和时间戳 1.在w ...

  5. openwrt的默认/etc/config/network文件是如何生成的?

    openwrt的network文件,或者说在/etc/config下的文件,都是动态生成的. 脚本的函数定义在openwrt1407/package/base-files/files/lib/func ...

  6. openwrt procd启动流程和脚本分析

    Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...

  7. Hello Shell

    shell是Linux平台的瑞士军刀,能够自动化完成很多工作.要了解UNIX 系统中可用的 Shell,可以使用 cat /etc/shells 命令.使用 chsh 命令 更改为所列出的任何 She ...

  8. OpenWRT学习笔记-1@WNDR3800

    很久以前买了一台二手wndr3800 放假了刷成op可以一耍.ar71xx,芯片还比较热门. 首先是刷机,准备使用OP CC 15.05 r46767,官方稳定版.把原装系统降级到1.0.0.16,就 ...

  9. sh语法入门学习

    玩linux都知道sh脚本的方便,但如何编写sh脚本却是像我这样的新手和菜鸟的难题.能不能编写得出来是一回事,了不了解又是另一回事.抱着好好学习,天天向上的精神,大家有空就看看吧,没有坏处的.下面来抄 ...

随机推荐

  1. 多测师讲解python _函数中参数__高级讲师肖sir

    函数中讲解参数: 形参和实参的认识 函数无参数的调用 函数单个参数的调用 函数多个参数的调用 # #调试函数给默认参数传新值,则函数使用新值 # 注意:当多种参数同时出现在函数中,默认参数要放在最后的 ...

  2. java中break、continue、return作用

    java中break.continue.return作用 0.首先要明确:break和continue是作用对象是循环体:而return的作用对象是方法 break:在执行完本次循环后,跳出所在的循环 ...

  3. linux(centos8):lnmp环境编译安装zabbix5.0

    一,zabbix的用途: zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案 zabbix能监视各种网络参数,保证服务器系统的安全运营: 并提供灵活的通知机制以 ...

  4. asp.net 获取网站根目录总结 Global.asax文件里获取获取网站根目录

    1:  获取网站根目录的方法有几种如: Server.MapPath(Request.ServerVariables["PATH_INFO"])Server.MapPath(&qu ...

  5. 第十二章 Linux三剑客之老三—grep

    一.Linux grep 命令用于查找文件里符合条件的字符串. Linux系统中的grep命令是一种功能强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.grep全称是Global ...

  6. Helium文档3-WebUI自动化-click点击

    前言 click点击方法在web UI自动化中使用频率非常高,此方法就是模拟鼠标左键单击动作 click入参说明 1.首先我们来分析一下click方法的代码 click(element):   &qu ...

  7. JS对象的各种操作

    对象由若干键值对组成 属性 都是为字符串类型,值 就可以为任意类型 var xiaoming= { name: '小明', 'school': 'No.1 School' }; 访问对象里面的属性,可 ...

  8. 结对项目的PS表格

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 60 80 Estimate 估计这个任务需要多少时间 10 ...

  9. Phoenix创建索引源码过程

    date: 2020-09-27 13:50:00 updated: 2020-09-28 16:30:00 Phoenix创建索引源码过程 org.apache.phoenix.index.Inde ...

  10. mysql幻读、MVCC、间隙锁、意向锁(IX\IS)

    IO即性能 顺序主键写性能很高,由于B+树的结构,主键如果是顺序的,则磁盘页的数据会按顺序填充,减少数据移动,随机主键则可能由于记录移动产生很多io 查询二级索引时,会再根据主键id获取数据页,产生一 ...