在 ubuntu shell 脚本中的 while 循环内使用消息结束 (EOM) 时出现语法错误

在 ubuntu shell 脚本中的 while 循环内使用消息结束 (EOM) 时出现语法错误

我有一个包含命令的代码,其中提示用户从菜单中显示的选项中选择一个选项。这需要重复执行几次,因此我使用了 while 循环。现在,我使用 EOM(消息结束)方法在提示时提供输入。在使用过程中,我注意到此方法在执行时会产生以下错误。我已将错误缩小到代码的这一部分(第 80 行到第 83 行),但无法解决此问题。

请帮我解决这个问题。

发生错误的行:

TEMP="q"
gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
$TEMP
EOM

错误:

./Run_Pull_Code.sh: 105: Syntax error: end of file unexpected (expecting "done")

请查看以下完整代码(请参阅此处的第 80 至 83 行):

#!/bin/sh
# The above comment sets the sh file to execute as an interpreter (Line by line)

# Finding the current working directory
BASEDIR=$(pwd)
echo "I am currently in the following directory:"
echo "$BASEDIR"
echo " "


##########################################################################################
# Setting the pulling code positions and decrements (All in nm)
##########################################################################################
DECREMENT=0.5      #Steps in nm
RANGE=1            #From the highest to the lowest position
MID_POS=9.327      #Observing the highest water molecule (O atom) of the water surface
INIT_POS=$( echo "$MID_POS + $RANGE" | bc -l)  # Initial position
LAST_POS=$( echo "$MID_POS - $RANGE" | bc -l)  # Final position
CURR_POS=$INIT_POS # Assigning the Initial position as the current position


LOOP_CNT=0
while [ 1 -eq "$(echo "${LAST_POS} <= ${CURR_POS}" | bc)" ]
do 
    # increment the value
    LOOP_CNT=$( echo "$LOOP_CNT + 1" | bc -l)
    DISTANCE=$CURR_POS

    # Setting the loop number (X) as the pull code number for simulation (X)
    SIM_CNT=$LOOP_CNT

    # Making the directories (1) X_Pull (2) X_Pull/Making
    DIR_NAME_MAIN=$SIM_CNT"_Pull"
    mkdir $DIR_NAME_MAIN
    DIR_NAME_MAKING=$SIM_CNT"_Pull/Making"
    mkdir $DIR_NAME_MAKING
    
    echo " "
    echo "I have made the directories."
    echo " "

    # Copying the files from prerequisites folder to the newly created folder
    cp Prerequisites/Avo_decanol.pdb Prerequisites/water_box.pdb $DIR_NAME_MAKING
    cp Prerequisites/simulation_file.mdp Prerequisites/topol.top $DIR_NAME_MAIN
    
    ##########################################################################################
    # Making the simulation box "pull_sim.gro"
    ##########################################################################################
    cd $DIR_NAME_MAKING
    #(1) Fix the distance of the decanol from the water surface and make the only decanol box with the same dimension as that of the water box
    DISTANCE=9.5 
    gmx_mpi editconf -f Avo_decanol.pdb -o Dec_box.pdb -center 2.5 2.5 $DISTANCE -box 5 5 12
    #(2) CREATING CONSTANT HEADER AND ENDER cat files in PDB format
    #The first 4 lines of any PDB file contains the information of the box size and the name, etc.
    #Just copy the four lines into a separate HEADER PDB file by the following command.
    sed -n '1,4p' Dec_box.pdb > HEADER.pdb
    #The last 2 lines are also common to all PDB files, hence copy these to a ENDER PDB file by the following command.
    sed -n '38,39p' Dec_box.pdb > ENDER.pdb
    #(3) Separate the decanol atom properties from its PDB file (line 5 to 37) by the follwing command
    sed -n '5,37p' Dec_box.pdb > file_1.pdb
    #(4) Separate the water atom properties from its PDB file (line 5 to 15004) by the follwing command
    sed -n '5,15004p' water_box.pdb > file_2.pdb
    #(5) Now connect all the above files with the water surface PDB file in the following sequence:
    cat HEADER.pdb file_1.pdb file_2.pdb ENDER.pdb > pull_sim.pdb
    #(6) Rearrange all the number of atoms in the pull_sim.pdb and convert it into a GRO file, pull_sim.gro file.
    gmx_mpi editconf -f pull_sim.pdb -o pull_sim.gro -center 2.5 2.5 6.0 -box 5.0 5.0 12.0 -resnr 1

    # Copying the recently made pull_sim.gro file from making folder to the previous folder
    cd ../
    cp Making/pull_sim.gro ./
        
    echo " "
    echo "The pull box has been created."
    echo " "
    
    ##########################################################################################
    # Starting the simulation
    ##########################################################################################
    # (1) Making index file
    TEMP="q"
    gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
    $TEMP
    EOM
    # (2) Creating tpr file from grompp module
    gmx_mpi grompp -f simulation_file.mdp -p topol.top -c pull_sim.gro -n index.ndx -maxwarn 0 -o nvt.tpr
    # Clearing all the contents
    clear
    echo " "
    echo "#####################*********** Pull Simulation: $LOOP_CNT ***********#####################"
    echo " "
    # (3) mdrun
    gmx_mpi mdrun -v -deffnm nvt -nb gpu -pme gpu -pmefft gpu -bonded gpu
        
    # Moving back to the main folder
    cd ../
    
    # Decrementing the distance for the next loop
    CURR_POS=$( echo "$CURR_POS - $DECREMENT" | bc -l)
done
    
#clear
echo " "
echo "Complete"
echo " "

答案1

Heredocs 不能像脚本的其余部分一样缩进(除非你使用-EOM,但你只能使用制表符缩进)。毕竟,Heredoc 的目的是让你写一些会出现的东西照原样。这意味着EOM不能像这样:

while something; 
do
    command <<EOM
    Hello!
    EOM
done  

相反,EOM(或您使用的任何其他标记)必须是该行上的唯一内容,因此其前后不能有空格或其他任何内容。如下所示:

while something; 
do
    command <<EOM
    Hello!
EOM
done  

另请注意,由于上述原因,前导空格也将包括在内,因此:

c=0;
while [ $c -eq 0 ]; 
do
    cat <<EOM
    Hello!
EOM
    let c++
done  

将打印:

$ foo.sh
    Hello!

虽然这样:

c=0;
while [ $c -eq 0 ]; 
do
    cat <<EOM
Hello!
EOM
    let c++
done  

将打印:

$ foo.sh
Hello!

最后,当运行脚本时,我收到不同的错误:

$ foo.sh
I am currently in the following directory:
/home/terdon/foo
 
/home/terdon/scripts/foo.sh: line 108: warning: here-document at line 84 delimited by end-of-file (wanted `EOM')
/home/terdon/scripts/foo.sh: line 109: syntax error: unexpected end of file

这是因为我没有提供相同的输入数据,而且由于您没有正确结束 EOM,您的数据可能正在由脚本处理,这就是您看到不同错误的原因。不过我希望我的修复程序可以消除它,因为它让我可以在我的机器上运行您的脚本直到结束。

相关内容