You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash嵌套循环读取CSV时仅执行一轮for循环问题排查

问题:Bash脚本仅执行一轮while循环后终止

现有一段Bash脚本,逻辑无错误,但仅能执行一轮while循环(遍历完ratio数组后即终止),而regime.csv包含30行4列数据。

存在问题的脚本

#!/bin/bash
csv_file="regime.csv"

ratio=(0.2 0.4 0.6 0.8)
while IFS=',' read -r col1 col2 col3 col4; do
    echo $col1
    echo $col2
    echo $col3
    echo $col4
    for rat in "${ratio[@]}"; do
        dir_name="${col4}_T${col1}_erate${col2}_${rat}"
        mkdir -p "$dir_name"
        cp in.C3N run.sh BNC.tersoff data_C3N.txt "$dir_name/"
        sed -i "s/\(variable[[:space:]]\+T equal \).*/\1${col1}/" "$dir_name/in.C3N"
        sed -i "s/\(variable[[:space:]]\+erate equal \).*/\1${col2}/" "$dir_name/in.C3N"
        sed -i "s/\(variable[[:space:]]\+reg equal \).*/\1${rat}/" "$dir_name/in.C3N"
        sed -i "s/\(variable[[:space:]]\+time equal \).*/\1${col3}/" "$dir_name/in.C3N"
        if [ "$col4" = "ZZ" ]; then
                sed -i '/^fix[[:space:]]\+deform Boundary deform 1 y erate/{
                N
                s/\(fix.* y erate.*\)\n\(fix.* x erate.*\)/\2\n\1/
                }' "$dir_name/in.C3N"
        fi

        # Change into the new directory, run run.sh, and return to the parent folder.
        pushd "$dir_name" > /dev/null
        ./run.sh
        popd > /dev/null
    done
done < "$csv_file"

可正常运行的对比示例脚本

#!/usr/bin/env bash

file="test.txt"       
a=(1 2 3)       

while IFS=' ' read -r col1 col2 rest; do
  for val in "${a[@]}"; do
    echo "$col1 $col2 and $val"
  done
done < "$file"

排查过程更新

更新1:CSV文件格式验证

regime.csv在Ubuntu的Jupyter-notebook中创建,前5行的cat -A输出如下:

cat -A regime.csv | head -5
100,0.01,978,AC$
1500,0.01,338,AC$
300,0.01,780,AC$
1000,0.01,425,AC$
1500,0.001,2901,AC$

更新2:run.sh内容

完整运行需要LAMMPS,也可将mpirun行替换为echo命令测试:

#!/bin/bash

LAMMPS_EXECUTABLE='/home/km9mb/Downloads/lammps-29Aug2024/src/lmp_mpi'
INPUT_FILE="in.C3N"

mpirun --oversubscribe -np 32 ${LAMMPS_EXECUTABLE} -in ${INPUT_FILE}

更新3:定位问题根源

注释掉脚本中的./run.sh后,脚本可以正常执行完所有CSV行,确认问题出在run.sh的执行上。

解决方法

在run.sh的mpirun命令中添加--stdin none参数,修改后的命令如下:

mpirun --stdin none --oversubscribe -np 32 ${LAMMPS_EXECUTABLE} -in ${INPUT_FILE}

原因说明:mpirun默认会继承父进程的标准输入,导致while循环读取CSV的输入流被抢占,循环提前终止。添加--stdin none参数后,mpirun不再占用标准输入,while循环可以正常读取完CSV的所有行。


内容的提问来源于stack exchange,提问作者Karen Tabar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:40:16