Puncte:0

Eroare de sintaxă în timpul utilizării Sfârșitul mesajului (EOM) într-o buclă while în scriptul shell ubuntu

drapel in

Am un cod care conține o comandă în care utilizatorului i se solicită să selecteze o opțiune dintre cele afișate în meniu. Acest lucru trebuie executat în mod repetat de mai multe ori, prin urmare am folosit bucla while. Acum, am folosit metoda EOM (Sfârșitul mesajului) pentru a da intrare atunci când vi se solicită. În timpul utilizării, am observat că această metodă produce următoarea eroare atunci când este executată. Am restrâns bug-ul la această parte a codului (linia 80 la 83) și nu reușesc să trec asta.

Vă rog să mă ajutați să rezolv asta.

Liniile în care apare eroarea:

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

Eroare:

./Run_Pull_Code.sh: 105: Eroare de sintaxă: sfârșitul fișierului neașteptat (se așteaptă „terminat”)

Vă rugăm să găsiți următorul cod complet (consultați rândurile de la 80 la 83 aici):

#!/bin/sh
# Comentariul de mai sus setează fișierul sh să fie executat ca interpret (linie cu linie)

# Găsirea directorului de lucru curent
BASEDIR=$(pwd)
echo „În prezent sunt în următorul director:”
echo „$BASEDIR”
ecou " "


#################################################################### ########################################
# Setarea pozițiilor și scăderilor codului de tragere (Toate în nm)
#################################################################### ########################################
DECREMENT=0,5 #Pași în nm
RANGE=1 #De la cea mai înaltă la cea mai joasă poziție
MID_POS=9.327 #Observarea celei mai înalte molecule de apă (atomul de O) de pe suprafața apei
INIT_POS=$( echo "$MID_POS + $RANGE" | bc -l) # Poziția inițială
LAST_POS=$( echo "$MID_POS - $RANGE" | bc -l) # Poziția finală
CURR_POS=$INIT_POS # Atribuirea poziției inițiale ca poziție curentă


LOOP_CNT=0
în timp ce [ 1 -eq "$(echo "${LAST_POS} <= ${CURR_POS}" | bc)" ]
do 
    # incrementa valoarea
    LOOP_CNT=$( ecou „$LOOP_CNT + 1” | bc -l)
    DISTANCE=$CURR_POS

    # Setarea numărului buclei (X) ca număr de cod de tragere pentru simulare (X)
    SIM_CNT=$LOOP_CNT

    # Realizarea directoarelor (1) X_Pull (2) X_Pull/Making
    DIR_NAME_MAIN=$SIM_CNT"_Pull"
    mkdir $DIR_NAME_MAIN
    DIR_NAME_MAKING=$SIM_CNT"_Trage/Efectuare"
    mkdir $DIR_NAME_MAKING
    
    ecou " "
    echo „Am făcut directoarele”.
    ecou " "

    # Copierea fișierelor din folderul de cerințe preliminare în folderul nou creat
    cp Cerințe preliminare/Avo_decanol.pdb Cerințe preliminare/water_box.pdb $DIR_NAME_MAKING
    cp Cerințe preliminare/simulation_file.mdp Cerințe preliminare/topol.top $DIR_NAME_MAIN
    
    #################################################################### ########################################
    # Realizarea casetei de simulare „pull_sim.gro”
    #################################################################### ########################################
    cd $DIR_NAME_MAKING
    #(1) Fixați distanța decanolului de la suprafața apei și faceți singura cutie de decanol cu ​​aceeași dimensiune ca cea a cutiei de apă
    DISTANTA=9,5 
    gmx_mpi editconf -f Avo_decanol.pdb -o Dec_box.pdb -center 2.5 2.5 $DISTANCE -box 5 5 12
    #(2) CREAREA fișierelor cat HEADER ȘI ENDER CONSTANT în format PDB
    #Primele 4 rânduri ale oricărui fișier PDB conțin informații despre dimensiunea casetei și numele etc.
    #Copiați doar cele patru linii într-un fișier separat HEADER PDB prin următoarea comandă.
    sed -n '1,4p' Dec_box.pdb > HEADER.pdb
    #Ultimele 2 linii sunt, de asemenea, comune tuturor fișierelor PDB, prin urmare copiați-le într-un fișier ENDER PDB prin următoarea comandă.
    sed -n '38,39p' Dec_box.pdb > ENDER.pdb
    #(3) Separați proprietățile atomului decanol de fișierul său PDB (linia 5 până la 37) prin următoarea comandă
    sed -n '5,37p' Dec_box.pdb > file_1.pdb
    #(4) Separați proprietățile atomului de apă din fișierul PDB (linia 5 până la 15004) prin următoarea comandă
    sed -n '5,15004p' water_box.pdb > file_2.pdb
    #(5) Acum conectați toate fișierele de mai sus cu fișierul PDB de la suprafața apei în următoarea secvență:
    cat HEADER.pdb fișier_1.pdb fișier_2.pdb ENDER.pdb > pull_sim.pdb
    #(6) Rearanjați tot numărul de atomi din pull_sim.pdb și convertiți-l într-un fișier GRO, fișier pull_sim.gro.
    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

    # Copierea fișierului pull_sim.gro creat recent din folderul de creare în folderul anterior
    cd ../
    cp Making/pull_sim.gro ./
        
    ecou " "
    echo „Cutia de tragere a fost creată”.
    ecou " "
    
    #################################################################### ########################################
    # Pornirea simulării
    #################################################################### ########################################
    # (1) Realizarea fișierului index
    TEMP="q"
    gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
    $TEMP
    EOM
    # (2) Crearea fișierului tpr din modulul grompp
    gmx_mpi grompp -f simulation_file.mdp -p topol.top -c pull_sim.gro -n index.ndx -maxwarn 0 -o nvt.tpr
    # Ștergerea întregului conținut
    clar
    ecou " "
    echo „####################************ Simulare de tragere: $LOOP_CNT *********** #####################"
    ecou " "
    # (3) mdrun
    gmx_mpi mdrun -v -deffnm nvt -nb gpu -pme gpu -pmefft gpu -bonded gpu
        
    # Mutarea înapoi la folderul principal
    cd ../
    
    # Scăderea distanței pentru următoarea buclă
    CURR_POS=$( echo "$CURR_POS - $DECREMENT" | bc -l)
Terminat
    
#clar
ecou " "
ecou "Complet"
ecou " "
terdon avatar
drapel cn
Care este eroarea? Și la ce intrare se așteaptă această comandă `gmx_mpi make_ndx`? Cum l-ați rula dacă nu ați folosi heredocs (EOM)? I-ai da un dosar? O sfoară?
terdon avatar
drapel cn
Și câteva comentarii generale: i) evitați utilizarea CAPS pentru numele variabilelor în scripturile shell. Prin convenție, variabilele de mediu globale sunt scrise cu majuscule, astfel încât să aveți propriile variabile în majuscule poate duce la coliziuni de nume de variabile care pot fi foarte greu de depanat. În general, este o practică bună să evitați majusculele în scripturile shell. ii) ***intotdeauna citati duble variabilele dvs.***. Consultați [Implicații de securitate ale uitării de a cita o variabilă în shell-urile bash/POSIX](https://unix.stackexchange.com/q/171346). iii) puteți incrementa o variabilă în mod nativ în shell, nu este nevoie de `bc`: `let LOOP_CNT++` sau `((LOOP_CNT++))`.
drapel in
Multumesc pentru sfat. Acum am editat și am menționat eroarea. Te rog să arunci o privire.
Puncte:2
drapel cn

Heredocs nu poate fi indentat ca restul scriptului (cu excepția cazului în care utilizați -EOM dar apoi puteți indenta numai cu file). La urma urmei, scopul heredoc-ului este să vă permită să scrieți ceva care va apărea asa cum este. Aceasta înseamnă că EOM nu poate fi asa:

în timp ce ceva; 
do
    comanda <<EOM
    Buna!
    EOM
Terminat  

În schimb, cel EOM (sau orice alt marcat pe care îl utilizați) trebuie să fie singurul lucru de pe linie, deci fără spații albe sau orice altceva înainte sau după el. Ca aceasta:

în timp ce ceva; 
do
    comanda <<EOM
    Buna!
EOM
Terminat  

De asemenea, rețineți că, din motivele menționate mai sus, va fi inclus și spațiul alb principal, astfel încât acesta:

c=0;
în timp ce [ $c -eq 0 ]; 
do
    pisica <<EOM
    Buna!
EOM
    lasă c++
Terminat  

Ar tipări:

$ foo.sh
    Buna!

În timp ce aceasta:

c=0;
în timp ce [ $c -eq 0 ]; 
do
    pisica <<EOM
Buna!
EOM
    lasă c++
Terminat  

Ar tipări:

$ foo.sh
Buna!

În cele din urmă, când rulez scriptul, primesc o eroare diferită:

$ foo.sh
Momentan ma aflu in urmatorul director:
/home/terdon/foo
 
/home/terdon/scripts/foo.sh: linia 108: avertisment: aici-document la linia 84 delimitat de sfârșitul fișierului (dorit „EOM”)
/home/terdon/scripts/foo.sh: linia 109: eroare de sintaxă: sfârșit neașteptat al fișierului

Acest lucru se va datora faptului că nu dau aceleași date de intrare și, din moment ce nu ați terminat corect EOM, datele dumneavoastră au fost probabil procesate de script și de aceea ați văzut o eroare diferită. Mă aștept, totuși, că remedierea mea va scăpa de ea, deoarece îmi permite să rulez scriptul până la sfârșit pe mașina mea.

muru avatar
drapel us
Heredoc-urile pot fi indentate, atunci când utilizați o cratimă înainte de cuvântul delimitator (de ex. `
terdon avatar
drapel cn
@muru adevărat, nu-mi amintesc niciodată asta, pur și simplu nu le indentează și las așa. Dar un punct bun, mulțumesc.
drapel in
Multumesc mult domnule. Acum problema mea a fost rezolvată.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.