关于shell中的一个命名引起的问题,局部变量

这篇具有很好参考价值的文章主要介绍了关于shell中的一个命名引起的问题,局部变量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

以下脚本并不完整,只是抽取的部分进行 问题讲解。。

# @brief:dynamically maintaining and updating the hostMap-
# if add a cd_burner, so add it's info to hostMap.
# @return:if check a change, so return 1, or return 0.
function updateHostmap()
{
    # check if the tag file exists. 
    # If it does, it indicates that the `enableSpecDriver`` in another terminal has not been completed;
    # so directly return...
    if [ -e ${BURN_FLAG_FILE} ];then
        echo "[DEBUG] tag-flag-file not write finish."
        return
    fi

    # is need to update the HOST_MAPFILE?
    isUpdateMapfile=0

    # assuming a computer has BURNER_COUNT CD-drivers
    srcArray=()  # like srN...
    for index in $(seq 0 ${BURNER_COUNT})
    do
        ch=$(printf "%c" $(expr $index+48))
        path="sr${ch}"
        srcArray+=(${path})
    done

    for srName in "${srcArray[@]}"       # srN
    do
        if [ -e "/dev/${srName}" ]; then        # /dev/srN
            # to get id_serial
            # if the burner contains a light-disk, The process of transitioning from disable -> enable,
            # it may take some time to load device information...
            while true
            do
                res=`udevadm info "/dev/${srName}" |grep ID_SERIAL=`
                regex="ID_SERIAL=(.*)"
                if [[ ${res} =~ $regex ]]; then
                    idd_serial=${BASH_REMATCH[1]}
                fi

                if [ ! -z ${idd_serial} ];then
                    echo "[DEBUG] detect a new device or enable device, and it's id_serial is [${idd_serial}]."
                    break
                else
                    echo "[DEBUG] detect a new device or enable device, but it has no id_serial. so, after sleep 3, obtain it again until it's id_seril not empty."
                    sleep 3     # length(idd_serial)=0
                fi
            done

            # first, determine whether the detected id_serial of the burner exists in array ENABLE_BURNER_ARRAY???
            # if so, this device is currently enabled and cannot be added as a new device for updates...
            ### call...
            unset ENABLE_BURNER_ARRAY[@]
            readEnableFile
            if [ ${#ENABLE_BURNER_ARRAY[@]} -eq 0 ]; then
                echo "[DEBUG] ENABLE_BURNER_ARRAY is empty."
            else
                echo "[DEBUG] ENABLE_BURNER_ARRAY value is:> ${ENABLE_BURNER_ARRAY[@]}"
            fi

            isContinue=1
            for item_id in "${ENABLE_BURNER_ARRAY[@]}"
            do
                if [ "$item_id" = "$idd_serial" ];then 
                    isContinue=0
                    continue
                fi
            done
            if [ $isContinue -eq 0 ];then
                continue
            fi
            
            ### plugging and unplugging...
            # [1]. it's a new device, so add a item to hostMap
            # [2]. not a new device, and this device has alreay in our hostMap(plugging and unplugging of `the same device`)
            # so update it's host in hostMap(Once the device is unplugged, it's host will change)
            devPath=$(ls -l /sys/block |grep ${srName})
            regex="/host([0-9]+)/"
            if [[ $devPath =~ $regex ]] && [ ! -z ${idd_serial} ]; then
                hostName="host${BASH_REMATCH[1]}"
                hostMap["${idd_serial}"]=${hostName} # like host["HL-DT-ST_DVDRAM_GUD1N_KYJL590433"]="host2"
                isUpdateMapfile=1
            fi

            # if a recording machine like XIN-KE that contains a robotic arm, 
            # /dev/srN is required during zero return initialization, 
            # or the door will eject back and forth...
            is_shouldDelay=0
            for vendor in "${VENDORS[@]}"
            do
                if [[ "$res" == *"$vendor"* ]];then
                    is_shouldDelay=1
                    break
                fi
            done

            if [ $is_shouldDelay -eq 1 ];then
                echo "[DEBUG] find all-in-one machine, delay for $ZERO_WAIT_TIME seconds to complete the zero return operation."
                sleep $ZERO_WAIT_TIME
            fi

            # then disable the scanned /dev/srN
            echo 0 > /sys/block/${srName}/device/delete
            echo "[DEBUG] detect a new device /dev/${srName}, so disable it... "
        fi
    done

    if [ ${isUpdateMapfile} -eq 1 ]; then
        return 1
    else
        return 0
    fi
}

片段分析

           while true
            do
                res=`udevadm info "/dev/${srName}" |grep ID_SERIAL=`
                regex="ID_SERIAL=(.*)"
                if [[ ${res} =~ $regex ]]; then
                    idd_serial=${BASH_REMATCH[1]}
                fi

                if [ ! -z ${idd_serial} ];then
                    echo "[DEBUG] detect a new device or enable device, and it's id_serial is [${idd_serial}]."
                    break
                else
                    echo "[DEBUG] detect a new device or enable device, but it has no id_serial. so, after sleep 3, obtain it again until it's id_seril not empty."
                    sleep 3     # length(idd_serial)=0
                fi
            done


主要留意idd_serial,实际这是一个全局变量,在函数外依然可以被正常访问。
上述逻辑主要是通过udevadm来提取 /dev/srN对应的 ID_SERIAL,
PC端共存在/dev/sr0和/dev/sr1两个光驱驱动。
首先,我们删除/dev/sr0和/dev/sr1,,,,,
然后重新扫描,是之前/dev/sr0所对应的设备被重新扫描出来,,,,
此时,将产生/dev/sr0,其会被我们的updateHostmap函数所捕获,并且idd_serial肯定会被赋值,即不为空。
后来再次将刚刚的/dev/sr0删除, 接着去扫描之前删除的/dev/sr1所对应的设备,被扫描后的该设备重新对应于/dev/sr0。
此时仍然会被updateHostmap所捕获。。。。。。。。。。。。。。
十分注意:执行 res=udevadm info "/dev/${srName}" |grep ID_SERIAL= 可能会返回空(因为/dev/sr0可能没有被加载完毕,,,),因为idd_serial之前已经被赋值了,,,所以流程会一直往下走,但是很明显,此时的这个idd_serial并不是我们想要的,它并不是重新被扫描后的设备对应的id_serial,,,,,而是一开始禁用后又启用的设备的id_serial。
于是,后面的逻辑就会因为idd_serial的错误值 而产生 差错。。。
导致后续的流程出现逻辑差错。。。。



解决方案
可以在函数中通关 local关键字 进行修饰,将其 idd_serial修饰为局部变量。。。

提醒:今后,为了避免这些问题,直接一律在函数中的变量全部声明为局部变量。

...
local idd_serial
...

当然还有其他一些解决方案
例如:可以对 res=udevadm info "/dev/${srName}" |grep ID_SERIAL=执行
的结果进行输出,,通过$?是否等于0来判断上述命令是否执行成功,如果$?返回1,表示失败,那就在继续获取,直到成功。。
另外,也可以在idd_serial被使用完后,在函数内部的最下面给其赋值为空,,,,也是可以的。。。
但是,,,以上两种做法都不好,,,通过local来控制是最完美的方案。。。。
文章来源地址https://www.toymoban.com/news/detail-524513.html

到了这里,关于关于shell中的一个命名引起的问题,局部变量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于Swift中闭包和OC中block对局部变量基本数据类型值的捕获

    翻了很多文章,发现关于Swift闭包关于上下文变量捕获这块,都没有说的很详细,或者Swift2这样的老版本已经不适用了,问了GPT也是和自己实验的结果不一样,记录下来。 首先,回顾一下OC中的block。 block对局部变量基本数据类型的捕获,是在创建时捕获了值,并保存副本在自

    2024年02月16日
    浏览(31)
  • 【Android】一个contentResolver引起的内存泄漏问题分析

    长时间的压力测试后,系统发生了重启,报错log如下 JNI ERROR (app bug): global reference table overflow (max=51200) global reference table overflow的log 08-08 04:11:53.052912   973  3243 F zygote64: indirect_reference_table.cc:256] JNI ERROR (app bug): global reference table overflow (max=51200) 08-08 04:11:53.053014   973  3243 F z

    2024年02月08日
    浏览(30)
  • shell中的变量

    1)常用系统变量 H O M E 、 HOME、 H OME 、 PWD、 S H E L L 、

    2024年02月11日
    浏览(21)
  • 记录一个Insert姿势引起的MySQL从库上查不到数据的问题

    转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 某测试环境的MySQL用了两台节点,主从同步结构。忽然有研发同学反映说MySQL的主从不同步了。他在测试代码功能的时候,调用接口在主库insert了一条数据,然后发现

    2024年01月22日
    浏览(28)
  • 认识环境变量和进程替换,实现一个简易的shell

    首先,在百度百科中,环境变量的解释是这样的: 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将

    2024年02月08日
    浏览(38)
  • 记一个因为Neo4j server版和Desktop版都装引起的问题

    经典错误 提示: DBMS failed to start: DBMS process terminated, see logs… Check the logs 我就去检查log,有个log.log里面是Neo4j @ 7687 is down.和Neo4j @ 7474 is down. 查了很久,没用,desktop版卸载重装好几次,没用 装server版的时候,配置了环境变量,删了之前配的环境变量,重启电脑。解决

    2024年02月11日
    浏览(25)
  • golang: 模仿 VictoriaMetrics 中的做法,通过把局部变量放在自定义 Context 对象中来做到hot path 的 0 alloc

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 使用 benchmark 压测过程中通常会出现这样的信息: 可以看见 f1 在每次运行都产生了 28 次内存分配。 gc 通常是 golang 最大的性能杀手,减少内存分配对性能提升非常明显

    2024年02月17日
    浏览(48)
  • 解决一个Sqoop抽数慢的问题,yarn的ATSv2嵌入式HBASE崩溃引起

     新搭建的一个Hadoop环境,用Sqoop批量抽数的时候发现特别慢,我们正常情况下是一个表一分钟左右,批量抽十几个表,也就是10分钟的样子,结果发现用了2个小时: 查看yarn日志  发现有如下情况: 主要有两个情况:  1.有大量的等待日志: Waiting for AsyncDispatcher to drain.Thre

    2024年02月14日
    浏览(25)
  • Android Studio 关于switch case中,R资源(局部R资源)找不到问题

    对比普通工程和Library工程的R文件发现,Library工程的R文件常量缺少final。 由于Library工程的可以包含资源文件,编译会生成R文件,多个Library中可能出现id冲突的问题。为了解决这个问题谷歌将Library工程R文件才从静态常量变为非常量。 然而switch语句的case中 必须是常量,而此

    2024年02月07日
    浏览(26)
  • Linux 问题 2. set -- 显示或设置 shell 特性及 shell 变量

    ^M是windos的dos文件格式特有的换行符,在linux上你可以通过   cat -A 文件名    看到这些隐藏字符。  解决方法:  如果需要转换,我们只需要转换文件格式即可。你可以选择直接在服务器上调整。包括如下三种方式。 (1)使用linux命令dos2unix filename,直接把文件转换为uni

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包