Bash中read -r遍历CSV文件仅处理首行的问题求助
问题:Bash脚本中
read -r仅处理CSV第一行的原因 原本以为read -r会逐行处理CSV内容,但实际只跑了第一行就停了,试着重定向去掉也没用。以下是我的Bash脚本:
#!/bin/bash while IFS=, read -r a b c; do d=$(echo "$c"|cut -d' ' -f1) for node in $(seq -f "somehost%02.0f" 01 29); do ssh -i ~/file.key user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*"; done >> tmp done < New.csv
对应的CSV文件内容:
0000007415597221,Authorized,11-SEP-23 10.40.27.000000 AM 0000007415596310,Authorized,11-SEP-23 10.40.30.000000 AM 0000007415596319,Authorized,11-SEP-23 10.40.31.000000 AM 0000007438025843,Authorized,17-SEP-23 05.56.34.000000 PM 0000007442152893,Authorized,18-SEP-23 07.36.24.000000 PM 0000007442154377,Authorized,18-SEP-23 07.36.34.000000 PM
原因与解决办法
核心问题是**ssh会占用脚本的标准输入**。
你的while循环通过< New.csv把CSV文件作为标准输入,但循环内的ssh命令默认会继承这个输入源。第一次循环执行ssh时,它会把CSV里剩下的所有内容都当作自己的输入消耗掉,后续的read命令就没有内容可读,循环直接终止。
两种修复方式:
给
ssh添加-n参数:该参数会将ssh的标准输入重定向到/dev/null,避免它消耗CSV的输入流。修改后的ssh命令如下:ssh -n -i ~/file.key user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*"使用非默认文件描述符读取CSV:把CSV文件绑定到非0的文件描述符(比如3),让
read从这个描述符读取内容,避开ssh的干扰。修改后的脚本:#!/bin/bash while IFS=, read -r a b c <&3; do d=${c%% *} # 替换echo+cut,用参数扩展更高效 for node in $(seq -f "somehost%02g" 1 29); do ssh -i ~/file.key user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*" done >> tmp done 3< New.csv
顺便提两个小优化:
- 提取日期部分
d可以用参数扩展${c%% *},无需启动额外进程,比echo "$c"|cut更高效。 seq的%02.0f可简化为%02g,起始值写1即可自动补前导零,写法更简洁。
内容的提问来源于stack exchange,提问作者imp
相关产品推荐
相关产品推荐

