关于 shell 下的 sleep 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
different
V2EX    Linux

关于 shell 下的 sleep 问题

  • &bsp;
  •   different 2019 年 6 月 1 日 4951 次点击
    这是一个创建于 2455 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近遇到下面这个问题,可能表达的不是很清楚。。 tasklist.txt 文件里面就只有三行

    1

    2

    3

    下面代码输出

    1

    (只循环了一次)

    #! /bin/bash

    cat tasklist.txt | while read lines

    do

    echo $lines cd /media/ice/0A9AD66165F33762/magnet_data/2019/修改 alpha/changeAlpha/runInMyComputer/80K/alpha0.01/50fs/80_1200 mpirun -np 1 ./bin/ASDMPI cff & sleep 1 

    done

    echo "end..............."

    下面代码输出

    1

    2

    3

    (循环了三次)

    #! /bin/bash

    cat tasklist.txt | while read lines

    do

    echo $lines cd /media/ice/0A9AD66165F33762/magnet_data/2019/修改 alpha/changeAlpha/runInMyComputer/80K/alpha0.01/50fs/80_1200 mpirun -np 1 ./bin/ASDMPI cff & 

    done

    echo "end..............."

    在我的电脑下有问题,在另一台电脑下没问题,奇怪了 这是何解??郁闷了

    第 1 条附言    2019 年 6 月 1 日
    最新修改:
    请问下面两段代码有什么不一样的:
    代码一:
    #以行读取
    oldIFS=$IFS;
    IFS=$'\n';
    for line in $(cat tasklist.txt )
    do
    echo $line
    nohup mpirun -np 1 ./bin/ASDMPI cff &
    sleep 1
    done
    kill -9 $(pgrep ASDMPI)

    以上代码输出
    1
    nohup: appending output to 'nohup.out'
    2
    nohup: appending output to 'nohup.out'
    3
    nohup: appending output to 'nohup.out'




    代码二:

    cat tasklist.txt | while read line
    do
    echo $line
    nohup mpirun -np 1 ./bin/ASDMPI cff &
    sleep 1
    done
    kill -9 $(pgrep ASDMPI)


    以上代码输出
    1
    nohup: appending output to 'nohup.out'


    测试环境为:Ubuntu18.04
    31 条回复    2019-06-03 16:13:19 +08:00
    guog
        1
    guog  
       2019 年 6 月 1 日 via Android
    贴下两台电脑的操作系统型号及版本呗,这让人怎么猜
    omph
        2
    omph  
       2019 年 6 月 1 日
    看看是不是换行符的问题
    PTLin
        3
    PTLin  
       2019 年 6 月 1 日
    wait 一下
    different
        4
    different  
    OP
       2019 年 6 月 1 日
    @guog
    @omph
    Ubuntu18.04 不行
    centos6.4 没问题
    至于换行符,应该不是这个问题。我之前在多台服务器上测试没问题的,然后今天直接拷贝在我电脑上跑就出问题了
    different
        5
    different  
    OP
       2019 年 6 月 1 日
    @PTLin wait 的话就“卡住了”鸭,等一条条指令执行完(可我的那个程序要执行几个小时的,,,)
    /div>
    Kobayashi
        6
    Kobayashi  
       2019 年 6 月 1 日 via Android
    set -x
    ys0290
        7
    ys0290  
       2019 年 6 月 1 日 via iPhone
    有什么问题?好像也没说
    different
        8
    different  
    OP
       2019 年 6 月 1 日
    @Kobayashi 我不是很懂,我对 shell 不是很理解,抱歉,可以详细说说看吗?感谢
    different
        9
    different  
    OP
       2019 年 6 月 1 日
    @ys0290 第一个代码比第二个代码多出了
    sleep 1
    这一行。
    但是执行结果就不一样了。
    前者循环了一次,后者循环了 3 次
    lionseun
        10
    lionseun  
       2019 年 6 月 1 日
    使用"{}"包裹 wihle 循环
    wikinee
        11
    wikinee  
       2019 年 6 月 1 日
    楼主这脚本好怪啊,我怎么就打印两行就不出了,参考网上的提示,改成这样:

    #!/bin/bash
    while read -r line || [[ -n ${line} ]]
    do
    echo "$line, do something"
    sleep 1
    done < tasklist.txt
    echo "end..............."
    different
        12
    different  
    OP
       2019 年 6 月 1 日
    @wikinee 你机器上面不应该输出两行吧。
    我把你的代码放在我的机器上测试有问题
    while read -r line || [[ -n ${line} ]]
    do
    echo $lines
    mpirun -np 1 ./bin/ASDMPI cff &
    sleep 2
    done<tasklist.txt

    症状:
    只打印一次
    调试:
    只要把 mpirun -np 1 ./bin/ASDMPI cff &
    或者 sleep 2 这两行代码的其中一行去掉就能打印 3 次。
    这是何解?


    目前我的解决方案是:
    i=0
    declare -a my_array
    while read lines
    do
    my_array[$i]=$lines
    i=`expr $i + 1`
    done<tasklist.txt
    for task in ${my_array[*]}
    do
    echo "exc"
    nohup mpirun -np 1 ./bin/ASDMPI cff &
    sleep 1
    done
    echo "end..............."

    但是我觉得本质和你的代码应该是一致的,可是结果却不一样。!!!!(也就是说,我用 for 循环就没问题)
    不知道我说清楚没。。?
    wikinee
        13
    wikinee  
       2019 年 6 月 2 日
    @different 输出两行的原因是最后一行无法读取,所以才加了 [[ -z ${line} ]] 判断,我测试的 tasklist.txt 也就三行最后没有空行,while 读不到最后一行这问题很典型
    另外,我也不知道你的 nohub xxxx 是什么命令,大概就是能持续输出结果的吧,我这边用 ping www.baidu.com 代替:

    #!/bin/bash
    while read -r line || [[ -n ${line} ]]
    do
    echo "$line"
    # 将日志重定向,将标准错误输出重定向到标准输出
    ping www.baidu.com > /dev/null 2>&1 &
    sleep 1
    done < tasklist.txt
    echo "end..............."

    另外,楼主执行的时候,要么把文件加可执行权限,直接 ./xxx.sh 要么 bash xxx.sh
    不要 sh xxx.sh ,因为 Debian 或者 Ubuntu 默认 shell 是 dash,其他系统不是。。。
    wikinee
        14
    wikinee  
       2019 年 6 月 2 日
    我自己写 shell 脚本也是百度编程法,遇到问题就去查[捂脸]
    后来我发现一个叫 shellcheck 的神器,类似 Python 的 pylint 或者 其他语言的 hint 那种,
    能提示你脚本哪里不合适,语法检查等等,安装之后还可以配置编辑器插件使用
    像 vscode 的 shellcheck 插件
    different
        15
    different  
    OP
       2019 年 6 月 2 日
    @wikinee 比较郁闷的是:
    我的
    nohup mpirun -np 1 ./bin/ASDMPI cff &
    这一行,如果用其他命令代替就不会有问题。。(可能我这一行代码的 ASDMPI 程序有错?但是我却能单独执行)
    说白了就是
    nohup mpirun -np 1 ./bin/ASDMPI cff &
    和 sleep 1
    不能同时存在。
    如果你用其他程序代替我的 ASDMPI 去测试,可能观察不到错误
    wikinee
        16
    wikinee  
       2019 年 6 月 2 日
    nohup mpirun -np 1 ./bin/ASDMPI cff & 改成:
    nohup mpirun -np 1 ./bin/ASDMPI cff > /dev/null 2>&1 &

    另外就怕命令自带阻塞。。。
    Kobayashi
        17
    Kobayashi  
       2019 年 6 月 2 日
    我是头一次听说不知道 set -x 是 debug,而且也不搜索的。不过鉴于你这问题比较特殊,还是来解释一下。

    问题在于 while read 循环每次从 stdin 读取内容,而你的后台命令 ASDMPI 不怎么厚道,趁你 sleep 1 时把 stdin 的内容给吃了。

    解决方案,方案 1,关闭后台命令的标准输入;方案 2,先把 tasklist.txt 内容逐行读入 array,for 循环 array。

    https://pastebin.com/Jz2sqvck

    另外,有时间好好学学 bash 是非常重要的。你第一条附言里 for line in $(cat tasklist.txt)存在空白格问题,这种问题往大了说,能把你搞得只能跑路。https://wiki.bash-hackers.org/scripting/tutoriallist
    Kobayashi
        18
    Kobayashi  
       2019 年 6 月 2 日
    for in 循环文件内容(仅限循环文件)属于山炮用法,谁用坑死谁。

    Why you don't read lines with "for",http://mywiki.wooledge.org/DontReadLinesWithFor

    我今天可能嘴巴比较臭,想说点大实话(一点建议)。有问题 Google,Stack Overflow,在一个灌水论坛提问技术是多么想不开?
    HEROic
        19
    HEROic  
       2019 年 6 月 2 日 via Android
    @Kobayashi 出现大佬
    ps:循环真的要注意空白行!
    different
        20
    different  
    OP
       2019 年 6 月 2 日
    @wikinee 我之前的命令就是你这个,后来我以为是我的命令问题,我就去掉了后面的> /dev/null 2>&1。。。
    different
        21
    different  
    OP
       2019 年 6 月 2 日
    @Kobayashi 啊哈,感谢感谢,还有个疑问,如果 ASDMPI 这个程序能吃掉 stdin 的内容,为何这种问题只存在某些 Linux 发行版里面?我的 Ubuntu18.04 有问题,centos6.4 没问题,。。
    Kobayashi
        22
    Kobayashi  
       2019 年 6 月 2 日
    @different 你两次贴的内容并不一样,后者没有 sleep 1。while read 可能和 ASDMPI 程序存在资源竞争,在外层循环语句 sleep 时,标准输入 stdin 被 ASDMPI 拿了?目前只能这样推测。
    ps1aniuge
        23
    ps1aniuge  
       2019 年 6 月 2 日
    shell 坑太多,一条 sleep 就把 shell 打 懵逼了!
    bash 已死,powershell 是脚本人的未来。

    请让我安利下 linux 版 powershell,谢谢:
    问:powershell 啥时候开源(+免费)的?
    答:
    2015 年小范围内部开源,2016 年开发者大会上,正式法律开源。



    问:开源后的 powershell,属于谁的财产?
    答:
    在遵守其开源协议的前提下。powershell 开源后。属于 [社区财产] 或 [任何人财产] 。



    问:谁是 powershell 开源免费的最大受益者?
    答:
    powershell 可以运行在,win,mac,ubuntu1404+,centos7,debian8+,suse12+,arch,alpine linux,树莓派 Raspbian,win10-iot,docker,snap-app,open-wrt 路由器等。
    这些系统使用者,是 powershell 开源免费的最大受益者。



    问:powershell 完全开源了么?
    答:
    不完全是。
    1 powershell 之所以简单、强大、好用。靠的是 powershell5.1+win 自带的 powershell 库。我们应该主要使用这些库。
    这些库,并没有开源。开源之前,是否免费我也不清楚。
    2 powershell6,powershell7,和相关的库,开源了。
    这里面的区别主要是 [win 自带软件,相关的 powershell 库] 。
    库数量很多,如 iis 的 ps 库。但这些 win 独有软件的 ps 库,跨不了平台。即便开源给 liux 也并没啥用。
    另外一些 win,linux 通用的 ps 库,比如 sqlserver 的 powershell 库,已经开源免费放在了 github 和 powershell 画廊。


    问:如何看待 bash,及 linux shell 脚本将来的地位,命运?
    问:powershell 在 linux 中的前景如何?
    答:
    就好像 [气泵射钉枪] 必将取代 [锤子] 一样,先进生产力必然代替落后的。
    就好像面向对象的 powershell,必然取代面向字符的 bat 那样。
    powershell 发展成熟后。以 bat,bash 为代表的,上一代面向字符串的脚本语言,面向字符串的命令,难免被边缘化。
    过几年后,开机启动脚本,特简单的脚本中,或许还残留有 bat,bash,字符串命令的身影。
    qinghon
        24
    qinghon  
       2019 年 6 月 2 日 via Android
    @ps1aniuge 气泵射钉枪至今没有取代锤子的地位
    面向对象的 c++至今没有取代面向函数的 c 的地位
    different
        25
    different  
    OP
       2019 年 6 月 2 日
    @Kobayashi
    一开始贴的内容有点乱。。。
    单纯看附言里面的内容的话,
    附言里面的两份代码均有 sleep
    但是在另一台机器( centos 6.4 )上测试
    均输出
    1
    nohup: appending output to 'nohup.out'
    2
    nohup: appending output to 'nohup.out'
    3
    nohup: appending output to 'nohup.out'

    而我的机器并不是。
    Kobayashi
        26
    Kobayashi  
       2019 年 6 月 3 日 via Android
    @different 这我就说不清了,无能为力。
    different
        27
    different  
    OP
       2019 年 6 月 3 日
    @Kobayashi 没事,已经非常感谢了。
    james122333
        28
    james122333  
       2019 年 6 月 3 日
    #!/bin/bash
    while read -r line
    do
    echo $line
    (mpirun -np 1 ~/bin/test &) &
    sleep 1
    done < tasklist.txt
    wait
    echo "end..............."
    james122333
        29
    james122333  
       2019 年 6 月 3 日
    打错
    james122333
        30
    james122333  
       2019 年 6 月 3 日
    #!/bin/bash
    while read -r line
    do
    echo $line
    (mpirun -np 1 ~/bin/test & wait) &
    sleep 1
    done < tasklist.txt
    wait
    echo "end..............."
    james122333
        31
    james122333  
       2019 年 6 月 3 日
    或者 mpirun 加上一个参数--stdin none
    会导向 stdin 的程序 有点恶心 不太好用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1765 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 08:04 PVG 16:04 LAX 00:04 JFK 03:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86