Điểm:0

Lỗi cú pháp trong khi sử dụng Kết thúc thư (EOM) bên trong vòng lặp while trong tập lệnh shell ubuntu

lá cờ in

Tôi có một mã chứa lệnh trong đó người dùng được nhắc chọn một tùy chọn từ những tùy chọn được hiển thị trong menu. Điều này cần được thực hiện lặp đi lặp lại nhiều lần, do đó tôi đã sử dụng vòng lặp while. Bây giờ, tôi đã sử dụng phương pháp EOM (Kết thúc thông báo) để cung cấp thông tin đầu vào khi được nhắc. Trong khi sử dụng, tôi nhận thấy rằng phương pháp này gây ra lỗi tiếp theo khi thực thi. Tôi đã thu hẹp lỗi ở phần này của mã (dòng 80 đến 83) và không thể vượt qua phần này.

Xin hãy giúp tôi giải quyết điều này.

Các dòng nơi xảy ra lỗi:

NHIỆT ĐỘ = "q"
gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
$TEMP
EOM

Lỗi:

./Run_Pull_Code.sh: 105: Lỗi cú pháp: kết thúc tệp không mong muốn (dự kiến ​​là "xong")

Vui lòng tìm mã đầy đủ sau đây (tham khảo các dòng 80 đến 83 tại đây):

#!/bin/sh
# Nhận xét trên đặt tệp sh để thực thi dưới dạng trình thông dịch (Từng dòng một)

# Tìm thư mục làm việc hiện tại
BASEDIR=$(pwd)
echo "Tôi hiện đang ở trong thư mục sau:"
tiếng vang "$BASEDIR"
tiếng vang " "


################################################# #######################################
# Đặt vị trí mã kéo và giảm dần (Tất cả tính bằng nm)
################################################# #######################################
GIẢM=0,5 #Bước theo nm
RANGE=1 #Từ vị trí cao nhất đến thấp nhất
MID_POS=9.327 #Quan sát phân tử nước cao nhất (nguyên tử O) của mặt nước
INIT_POS=$( echo "$MID_POS + $RANGE" | bc -l) # Vị trí ban đầu
LAST_POS=$( echo "$MID_POS - $RANGE" | bc -l) # Vị trí cuối cùng
CURR_POS=$INIT_POS # Chỉ định vị trí Ban đầu làm vị trí hiện tại


LOOP_CNT=0
trong khi [ 1 -eq "$(echo "${LAST_POS} <= ${CURR_POS}" | bc)" ]
làm 
    # tăng giá trị
    LOOP_CNT=$( tiếng vang "$LOOP_CNT + 1" | bc -l)
    DISTANCE=$CURR_POS

    # Đặt số vòng lặp (X) làm số mã kéo cho mô phỏng (X)
    SIM_CNT=$LOOP_CNT

    # Tạo thư mục (1) X_Pull (2) X_Pull/Making
    DIR_NAME_MAIN=$SIM_CNT"_Pull"
    mkdir $DIR_NAME_MAIN
    DIR_NAME_MAKING=$SIM_CNT"_Kéo/Làm"
    mkdir $DIR_NAME_MAKING
    
    tiếng vang " "
    echo "Tôi đã tạo các thư mục."
    tiếng vang " "

    # Sao chép các tệp từ thư mục điều kiện tiên quyết sang thư mục mới tạo
    cp Điều kiện tiên quyết/Avo_decanol.pdb Điều kiện tiên quyết/water_box.pdb $DIR_NAME_MAKING
    cp Điều kiện tiên quyết/simulation_file.mdp Điều kiện tiên quyết/topol.top $DIR_NAME_MAIN
    
    ################################################# #######################################
    # Làm hộp mô phỏng "pull_sim.gro"
    ################################################# #######################################
    cd $DIR_NAME_MAKING
    #(1) Cố định khoảng cách của decanol với mặt nước và tạo hộp decanol duy nhất có cùng kích thước với hộp nước
    KHOẢNG CÁCH=9.5 
    gmx_mpi editconf -f Avo_decanol.pdb -o Dec_box.pdb -center 2.5 2.5 $DISTANCE -box 5 5 12
    #(2) TẠO các tệp mèo CONSTANT HEADER VÀ ENDER ở định dạng PDB
    # 4 dòng đầu tiên của bất kỳ tệp PDB nào chứa thông tin về kích thước hộp và tên, v.v.
    #Chỉ cần sao chép bốn dòng vào một tệp HEADER PDB riêng biệt bằng lệnh sau.
    sed -n '1,4p' Dec_box.pdb > HEADER.pdb
    # 2 dòng cuối cùng cũng chung cho tất cả các tệp PDB, do đó hãy sao chép các dòng này vào tệp PDB ENDER bằng lệnh sau.
    sed -n '38,39p' Dec_box.pdb > ENDER.pdb
    #(3) Tách thuộc tính nguyên tử decanol khỏi tệp PDB của nó (dòng 5 đến 37) bằng lệnh follwing
    sed -n '5,37p' Dec_box.pdb > file_1.pdb
    #(4) Tách các thuộc tính nguyên tử nước khỏi tệp PDB của nó (dòng 5 đến 15004) bằng lệnh follwing
    sed -n '5,15004p' water_box.pdb > file_2.pdb
    #(5) Bây giờ kết nối tất cả các tệp trên với tệp PDB mặt nước theo trình tự sau:
    mèo HEADER.pdb file_1.pdb file_2.pdb ENDER.pdb > pull_sim.pdb
    #(6) Sắp xếp lại tất cả số nguyên tử trong pull_sim.pdb và chuyển đổi nó thành tệp GRO, tệp 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

    # Sao chép tệp pull_sim.gro được tạo gần đây từ thư mục tạo sang thư mục trước đó
    đĩa CD ../
    Làm cp/pull_sim.gro ./
        
    tiếng vang " "
    echo "Hộp kéo đã được tạo."
    tiếng vang " "
    
    ################################################# #######################################
    # Bắt đầu mô phỏng
    ################################################# #######################################
    # (1) Tạo tệp chỉ mục
    NHIỆT ĐỘ = "q"
    gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
    $TEMP
    EOM
    # (2) Tạo tệp tpr từ mô-đun grompp
    gmx_mpi grompp -f Simulation_file.mdp -p topol.top -c pull_sim.gro -n index.ndx -maxwarn 0 -o nvt.tpr
    # Xóa tất cả nội dung
    xa lạ
    tiếng vang " "
    echo "#####################*********** Kéo mô phỏng: $LOOP_CNT *********** #####################"
    tiếng vang " "
    # (3) mdrun
    gmx_mpi mdrun -v -deffnm nvt -nb gpu -pme gpu -pmefft gpu -bonded gpu
        
    # Di chuyển trở lại thư mục chính
    đĩa CD ../
    
    # Giảm khoảng cách cho vòng lặp tiếp theo
    CURR_POS=$( echo "$CURR_POS - $DECREMENT" | bc -l)
xong
    
#xa lạ
tiếng vang " "
tiếng vang "Hoàn thành"
tiếng vang " "
terdon avatar
lá cờ cn
Lỗi là gì? Và lệnh `gmx_mpi make_ndx` này mong đợi đầu vào nào? Bạn sẽ chạy nó như thế nào nếu bạn không sử dụng heredocs (EOM)? Bạn sẽ chuyển nó một tập tin? Một chuỗi?
terdon avatar
lá cờ cn
Và một số nhận xét chung: i) tránh sử dụng CAPS cho tên biến trong shell script. Theo quy ước, các biến môi trường chung được viết hoa, vì vậy việc viết hoa các biến của riêng bạn có thể dẫn đến xung đột tên biến, điều này có thể rất khó gỡ lỗi. Nói chung, nên tránh viết hoa trong tập lệnh shell. ii) *** luôn trích dẫn hai lần các biến của bạn ***. Xem [Ý nghĩa bảo mật của việc quên trích dẫn một biến trong bash/POSIX shell](https://unix.stackexchange.com/q/171346). iii) bạn có thể tăng một biến tự nhiên trong trình bao, không cần `bc`: `let LOOP_CNT++` hoặc `((LOOP_CNT++))`.
lá cờ in
Cảm ơn vì lời khuyên của bạn. Bây giờ tôi đã chỉnh sửa và đề cập đến lỗi. Xin vui lòng có một cái nhìn.
Điểm:2
lá cờ cn

Heredocs không thể được thụt vào như phần còn lại của tập lệnh (trừ khi bạn sử dụng -EOM nhưng sau đó bạn chỉ có thể thụt lề bằng các tab). Xét cho cùng, mục đích của heredoc là cho phép bạn viết thứ gì đó sẽ xuất hiện như là. Điều này có nghĩa là EOM không thể như thế này:

trong khi một cái gì đó; 
làm
    lệnh <<EOM
    Xin chào!
    EOM
xong  

Thay vào đó, EOM (hoặc bất kỳ dấu nào khác mà bạn sử dụng) cần phải là thứ duy nhất trên dòng, vì vậy không có khoảng trắng hoặc bất kỳ thứ gì khác trước hoặc sau nó. Như thế này:

trong khi một cái gì đó; 
làm
    lệnh <<EOM
    Xin chào!
EOM
xong  

Ngoài ra, lưu ý rằng vì những lý do đã đề cập ở trên, khoảng trắng hàng đầu cũng sẽ được đưa vào, do đó:

c=0;
trong khi [ $c -eq 0 ]; 
làm
    con mèo <<EOM
    Xin chào!
EOM
    hãy để c ++
xong  

Sẽ in:

$ foo.sh
    Xin chào!

Trong khi điều này:

c=0;
trong khi [ $c -eq 0 ]; 
làm
    con mèo <<EOM
Xin chào!
EOM
    hãy để c ++
xong  

Sẽ in:

$ foo.sh
Xin chào!

Cuối cùng, khi chạy tập lệnh của bạn, tôi gặp một lỗi khác:

$ foo.sh
Tôi hiện đang ở trong thư mục sau:
/nhà/terdon/foo
 
/home/terdon/scripts/foo.sh: dòng 108: cảnh báo: tài liệu tại đây ở dòng 84 được phân tách bằng phần cuối của tệp (muốn có `EOM')
/home/terdon/scripts/foo.sh: dòng 109: lỗi cú pháp: kết thúc tệp không mong muốn

Điều này là do tôi không cung cấp cùng một dữ liệu đầu vào và do bạn không kết thúc EOM đúng cách nên dữ liệu của bạn có thể đang được tập lệnh xử lý và đó là lý do tại sao bạn thấy một lỗi khác. Tôi hy vọng bản sửa lỗi của tôi sẽ loại bỏ nó, vì nó cho phép tôi chạy tập lệnh của bạn đến cuối trên máy của tôi.

muru avatar
lá cờ us
Heredocs có thể được thụt lề, khi bạn sử dụng dấu gạch nối ở đầu trước từ phân cách (ví dụ: `
terdon avatar
lá cờ cn
@muru đúng, tôi không bao giờ nhớ điều đó, tôi chỉ không thụt lề chúng và để nó ở đó. Nhưng điểm tốt, cảm ơn.
lá cờ in
Cảm ơn ông rất nhiều. Bây giờ vấn đề của tôi đã được giải quyết.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.