작업 예약을 위해 20개 폴더에 파일을 반복적으로 작성하기 위해 다음 코드를 사용하고 있습니다.
#!/bin/bash
for i in {1..20}
do
cd conf$i
cp ../nvt.mdp $PWD
cp ../topol.top $PWD
grompp -v -f nvt.mdp -c conf$i.gro -p topol.top -o conf_nvt$i.tpr >> nvt.log
cat<<KHIK >> run_nvt$i.pbs
#!/bin/bash
#PBS -l nodes=1:ppn=16
#PBS -l walltime=120:00:00
#PBS -N GROMACS:TAUAT_P
#PBS -q blaze
#PBS -j oe
#PBS -V
cd \$PBS_O_WORKDIR
export I_MPI_DEVICE=rdma
/home/apps/ics/impi/latest/bin64/mpiexec.hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm conf_nvt$i
KHIK
cd ..
done
이상한 오류가 발생합니다. 어떤 변경이 필요한지 알려주실 수 있나요?
./umbrnvt.sh: line 22: warning: here-document at line 9 delimited by end-of-file (wanted `KHIK')
./umbrnvt.sh: line 23: syntax error: unexpected end of file
답변1
줄 시작 부분에 닫는 태그가 있어야 합니다. 따라서 스크립트는 다음과 같아야 합니다.
#!/bin/bash
for i in {1..20}
do
cd conf$i
cp ../nvt.mdp $PWD
cp ../topol.top $PWD
grompp -v -f nvt.mdp -c conf$i.gro -p topol.top -o conf_nvt$i.tpr >> nvt.log
cat<<KHIK >> run_nvt$i.pbs
#!/bin/bash
#PBS -l nodes=1:ppn=16
#PBS -l walltime=120:00:00
#PBS -N GROMACS:TAUAT_P
#PBS -q blaze
#PBS -j oe
#PBS -V
cd \$PBS_O_WORKDIR
export I_MPI_DEVICE=rdma
/home/apps/ics/impi/latest/bin64/mpiexec.hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm conf_nvt$i
KHIK
cd ..
done
그렇지 않으면 bash는 KHIK를 블록 끝으로 인식하지 않습니다.
답변2
우선, 이 내용을 다른 사람이 언급한 적이 없으므로 해당 오류는 관련이 없습니다 cat
. nl
, od
, 와 같은 프로그램 tr
이나 심지어 1 과 같은 존재하지 않는 명령 에서도 동일한 오류가 발생합니다.dog
unicorn
tribble
실제 대답은 .as <<-
대신에 말해야 한다는 것입니다.<<
또 다른 대답거의 (그러나 완전히는 아니지만) 문제는 를 사용할 때 <<
쉘이 KHIK
"여기 문서"를 종료하는 줄에서 유일한 구분 기호 단어(예제에서는)를 찾는다는 것입니다. ,,,심지어 는 있을 수 없습니다 FOOKHIKBAR
. 를 사용하면 셸은 여기 문서의 각 줄 시작 부분에 있는 모든 탭을 제거하므로 정상적으로 보입니다.FOO KHIK BAR
KHIK FU
TabKHIK
<<-
TabKHIK
KHIK
하지만 똑같이 중요한 질문은 다음과 같습니다.
cat<<KHIK >> run_nvt$i.pbs
#!/bin/bash
#PBS -l nodes=1:ppn=16
#PBS -l walltime=120:00:00
#PBS -N GROMACS:TAUAT_P
#PBS -q blaze
#PBS -j oe
#PBS -V
cd \$PBS_O_WORKDIR
export I_MPI_DEVICE=rdma
/home/apps/ics/impi/latest/bin64/mpiexec.hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm conf_nvt$i
KHIK
그러면 당신은 얻을 것이다
#!/bin/bash #PBS -l 노드=1:ppn=16 #PBS -l 월타임=120:00:00 #PBS -N GROMACS:TAUAT_P #PBS -q 불꽃 #PBS-조이 #PBS-V CD $PBS_O_WORKDIR 내보내기I_MPI_DEVICE=rdma /home/apps/ics/impi/latest/bin64/mpiexec.Hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm conf_nvt{의 가치 $i}
존재하다 run_nvt$i.pbs
. 그 좋지 않다. "shebang"( #!
라인)이 제대로 작동 하려면 #!
해당 라인의 처음 두 문자여야 합니다. 다른 답변의 조언을 따르면 스크립트 run_nvt$i.pbs
에는 존중/인식되지 않는 shebang이 있으며 /bin/sh
다른 쉘과 함께 실행될 수 있습니다 (제외 bash
) - 참조이 답변더 알아보기. (첫 번째 줄의 공백이 아닌 첫 번째 문자는 이므로 #
해당 줄은 주석으로 처리됩니다. 이것은 shebang 작동 방식에서 중요하면서도 종종 간과되는 측면입니다.)
질문 본문과 관련이 없습니다. 타당한 이유가 없고 현재 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: "$i"
및 )를 인용해야 합니다."$PBS_O_WORKDIR"
공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?그리고bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험. 그리고 "$PWD"
생각만큼 자주 사용할 필요는 없습니다 . 일반적으로 충분합니다..
. 그리고 (IMNSHO) 가능할 때마다 공백을 사용하여 가독성에 도움이 됩니다. 따라서 다음과 같이 스크립트를 수정하는 것이 좋습니다.
#!/bin/bash
for i in {1..20}
do
cd "conf$i"
cp ../nvt.mdp .
cp ../topol.top .
grompp -v -f nvt.mdp -c conf$i.gro -p topol.top -o "conf_nvt$i.tpr" >> nvt.log
cat <<- KHIK >> "run_nvt$i.pbs"
#!/bin/bash
#PBS -l nodes=1:ppn=16
#PBS -l walltime=120:00:00
#PBS -N GROMACS:TAUAT_P
#PBS -q blaze
#PBS -j oe
#PBS -V
cd "\$PBS_O_WORKDIR"
export I_MPI_DEVICE=rdma
/home/apps/ics/impi/latest/bin64/mpiexec.hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm "conf_nvt$i"
KHIK
cd ..
done
앞과 뒤의 공백 <<-
과 추가 따옴표를 기록해 두십시오.
내가 좋아하는 스타일 중 하나는 여기에서 문서를 들여쓰는 것입니다.
︙
grompp -v -f nvt.mdp -c conf$i.gro -p topol.top -o "conf_nvt$i.tpr" >> nvt.log
cat <<- KHIK >> "run_nvt$i.pbs"
#!/bin/bash
#PBS -l nodes=1:ppn=16
#PBS -l walltime=120:00:00
#PBS -N GROMACS:TAUAT_P
#PBS -q blaze
#PBS -j oe
#PBS -V
cd "\$PBS_O_WORKDIR"
export I_MPI_DEVICE=rdma
/home/apps/ics/impi/latest/bin64/mpiexec.hydra /home/braf/md/gromacs-4.5.6/bin/mdrun_mpi -deffnm "conf_nvt$i"
KHIK
cd ..
︙
나는 이것이 스크립트를 더 쉽게 살펴보고 어떤 줄이 지금 실행 중인 명령이고 어떤 줄이 데이터인지(예: 나중에 실행될 수 있는 스크립트에 대한 입력) 확인하는 것을 더 쉽게 만든다고 믿습니다.
chmod +x "run_nvt$i.pbs"
PS 언젠가는 하고 싶지 않으신가요 ?
__________
1오늘 나는 배웠다예프로그램이 호출됩니다dog
그리고unicorn
.