关于 shell 下的 sleep 问题

2019-06-01 14:15:49 +08:00
 different

最近遇到下面这个问题,可能表达的不是很清楚。。 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..............."

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

4503 次点击
所在节点    Linux
31 条回复
guog
2019-06-01 15:15:55 +08:00
贴下两台电脑的操作系统型号及版本呗,这让人怎么猜
omph
2019-06-01 15:19:36 +08:00
看看是不是换行符的问题
PTLin
2019-06-01 19:14:07 +08:00
wait 一下
different
2019-06-01 20:05:07 +08:00
@guog
@omph
Ubuntu18.04 不行
centos6.4 没问题
至于换行符,应该不是这个问题。我之前在多台服务器上测试没问题的,然后今天直接拷贝在我电脑上跑就出问题了
different
2019-06-01 20:13:50 +08:00
@PTLin wait 的话就“卡住了”鸭,等一条条指令执行完(可我的那个程序要执行几个小时的,,,)
Kobayashi
2019-06-01 20:17:49 +08:00
set -x
ys0290
2019-06-01 20:18:56 +08:00
有什么问题?好像也没说
different
2019-06-01 20:35:03 +08:00
@Kobayashi 我不是很懂,我对 shell 不是很理解,抱歉,可以详细说说看吗?感谢
different
2019-06-01 20:35:53 +08:00
@ys0290 第一个代码比第二个代码多出了
sleep 1
这一行。
但是执行结果就不一样了。
前者循环了一次,后者循环了 3 次
lionseun
2019-06-01 21:03:24 +08:00
使用"{}"包裹 wihle 循环
wikinee
2019-06-01 21:21:39 +08:00
楼主这脚本好怪啊,我怎么就打印两行就不出了,参考网上的提示,改成这样:

#!/bin/bash
while read -r line || [[ -n ${line} ]]
do
echo "$line, do something"
sleep 1
done < tasklist.txt
echo "end..............."
different
2019-06-01 22:09:28 +08:00
@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
2019-06-02 08:08:50 +08:00
@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
2019-06-02 08:15:36 +08:00
我自己写 shell 脚本也是百度编程法,遇到问题就去查[捂脸]
后来我发现一个叫 shellcheck 的神器,类似 Python 的 pylint 或者 其他语言的 hint 那种,
能提示你脚本哪里不合适,语法检查等等,安装之后还可以配置编辑器插件使用
像 vscode 的 shellcheck 插件
different
2019-06-02 09:00:08 +08:00
@wikinee 比较郁闷的是:
我的
nohup mpirun -np 1 ./bin/ASDMPI cff &
这一行,如果用其他命令代替就不会有问题。。(可能我这一行代码的 ASDMPI 程序有错?但是我却能单独执行)
说白了就是
nohup mpirun -np 1 ./bin/ASDMPI cff &
和 sleep 1
不能同时存在。
如果你用其他程序代替我的 ASDMPI 去测试,可能观察不到错误
wikinee
2019-06-02 09:15:13 +08:00
nohup mpirun -np 1 ./bin/ASDMPI cff & 改成:
nohup mpirun -np 1 ./bin/ASDMPI cff > /dev/null 2>&1 &

另外就怕命令自带阻塞。。。
Kobayashi
2019-06-02 09:30:36 +08:00
我是头一次听说不知道 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
2019-06-02 09:42:44 +08:00
for in 循环文件内容(仅限循环文件)属于山炮用法,谁用坑死谁。

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

我今天可能嘴巴比较臭,想说点大实话(一点建议)。有问题 Google,Stack Overflow,在一个灌水论坛提问技术是多么想不开?
HEROic
2019-06-02 09:43:41 +08:00
@Kobayashi 出现大佬
ps:循环真的要注意空白行!
different
2019-06-02 10:05:33 +08:00
@wikinee 我之前的命令就是你这个,后来我以为是我的命令问题,我就去掉了后面的> /dev/null 2>&1。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/569731

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX