最近遇到下面这个问题,可能表达的不是很清楚。。 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
guog 2019-06-01 15:15:55 +08:00 via Android
贴下两台电脑的操作系统型号及版本呗,这让人怎么猜
|
2
omph 2019-06-01 15:19:36 +08:00
看看是不是换行符的问题
|
3
PTLin 2019-06-01 19:14:07 +08:00
wait 一下
|
4
different OP |
6
Kobayashi 2019-06-01 20:17:49 +08:00 via Android
set -x
|
7
ys0290 2019-06-01 20:18:56 +08:00 via iPhone
有什么问题?好像也没说
|
9
different OP |
10
lionseun 2019-06-01 21:03:24 +08:00
使用"{}"包裹 wihle 循环
|
11
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..............." |
12
different OP @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 循环就没问题) 不知道我说清楚没。。? |
13
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,其他系统不是。。。 |
14
wikinee 2019-06-02 08:15:36 +08:00
我自己写 shell 脚本也是百度编程法,遇到问题就去查[捂脸]
后来我发现一个叫 shellcheck 的神器,类似 Python 的 pylint 或者 其他语言的 hint 那种, 能提示你脚本哪里不合适,语法检查等等,安装之后还可以配置编辑器插件使用 像 vscode 的 shellcheck 插件 |
15
different OP @wikinee 比较郁闷的是:
我的 nohup mpirun -np 1 ./bin/ASDMPI cff & 这一行,如果用其他命令代替就不会有问题。。(可能我这一行代码的 ASDMPI 程序有错?但是我却能单独执行) 说白了就是 nohup mpirun -np 1 ./bin/ASDMPI cff & 和 sleep 1 不能同时存在。 如果你用其他程序代替我的 ASDMPI 去测试,可能观察不到错误 |
16
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 & 另外就怕命令自带阻塞。。。 |
17
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 |
18
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,在一个灌水论坛提问技术是多么想不开? |
20
different OP @wikinee 我之前的命令就是你这个,后来我以为是我的命令问题,我就去掉了后面的> /dev/null 2>&1。。。
|
21
different OP @Kobayashi 啊哈,感谢感谢,还有个疑问,如果 ASDMPI 这个程序能吃掉 stdin 的内容,为何这种问题只存在某些 Linux 发行版里面?我的 Ubuntu18.04 有问题,centos6.4 没问题,。。
|
22
Kobayashi 2019-06-02 10:29:00 +08:00
@different 你两次贴的内容并不一样,后者没有 sleep 1。while read 可能和 ASDMPI 程序存在资源竞争,在外层循环语句 sleep 时,标准输入 stdin 被 ASDMPI 拿了?目前只能这样推测。
|
23
ps1aniuge 2019-06-02 12:37:04 +08:00
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,字符串命令的身影。 |
24
qinghon 2019-06-02 16:08:09 +08:00 via Android
@ps1aniuge 气泵射钉枪至今没有取代锤子的地位
面向对象的 c++至今没有取代面向函数的 c 的地位 |
25
different OP @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' 而我的机器并不是。 |
28
james122333 2019-06-03 15:20:40 +08:00
#!/bin/bash
while read -r line do echo $line (mpirun -np 1 ~/bin/test &) & sleep 1 done < tasklist.txt wait echo "end..............." |
29
james122333 2019-06-03 15:26:10 +08:00
打错
|
30
james122333 2019-06-03 15:31:25 +08:00
#!/bin/bash
while read -r line do echo $line (mpirun -np 1 ~/bin/test & wait) & sleep 1 done < tasklist.txt wait echo "end..............." |
31
james122333 2019-06-03 16:13:19 +08:00
或者 mpirun 加上一个参数--stdin none
会导向 stdin 的程序 有点恶心 不太好用 |