I have the following bash script which works fine but only goes through the for
loop once!
#!/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"
I can't find where the logic is wrong. So it goes through the ratio values 0.2, 0.4, 0.6, 0.8 and then ends. The csv file has 30 lines with 4 columns.
I have this sample code which works fine and I don't know what the difference is.
#!/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"
Thank you.
** Update 1:**
The regime.csv file is created in Ubuntu using Jupyter-notebook.Here is the output of:
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$
Update 2:
You can't technically run the files because you need LAMMPS installed but and it is a pain to do so, but you can replace the mpirun line in the run.sh file to do a simple echo or something.
run.sh:
#!/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}
UPDATE 3
It is definitely the run.sh file that is causing the problem. When I comment out the "./run.sh" the whole thing works just fine! Does anyone knows how to fix this?
SOLVED!!!!
Thanks to @pjh I was able to fix it by adding "--stdin none" flag to my "mpirun" command in "run.sh" file! It turned out that run.sh was eating my stdin terminating the while loop!
regime.csv
has windows line endings, Or you need tocd
in a subshell.regime.csv
; consider making a copy of the main script, comment out everything inside thefor
loop and add something likeecho "for:$col1:$rat"
then run the script; if the script loops successfully then incrementally uncomment some lines in thefor
loop and run the script again; repeat until you find what's breaking thefor
loop; also, by any chance doesrun.sh
modifyregime.csv
?regime.csv
file (2 of the lines end in,ZZ
), made arun.sh
that simply doesecho 'hi'
, and rantouch
on the other data files; ran the script and it cycled through both thewhile
andfor
loop as expected while creating a slew of*erate*
subdirectories (with each subdirectory containing the 4cp'd
files)ssh
orffmpeg
) in yourrun.sh
reads standard input and thus consumes all the lines that should be read by the loop. See While loop stops reading after the first line in Bash. Also see the How to keep other commands from "eating" the input section of BashFAQ/001 (How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?).