간단한 cp 명령이 작동하지 않습니다(셸 스크립트 내에서 클러스터에서 sbatch 커밋 사용).

간단한 cp 명령이 작동하지 않습니다(셸 스크립트 내에서 클러스터에서 sbatch 커밋 사용).

저는 RHEL을 실행하는 클러스터에서 작업하고 있으며 다음 명령을 사용하여 작업을 제출하고 있습니다.

sbatch MyScript.sh

MyScript.sh의 내용은 다음과 같습니다.

#!/bin/sh

# ....
# Other SBATCH related commands are here
# ....

## Script begins here

for d in lambda.*/
do

  cd ${d%?}
  echo "Changed Directory"
  cp -r ../Transfer/${d%?}/ENMIN/  ./
  echo "Transferred"
  rm -rf ../Transfer/${d%?}
  echo "Removed"
  cd ENMIN
  time mpirun -np $SLURM_NTASKS gmx_mpi mdrun -v -stepout 1000 -s enmin.tpr -deffnm enmin

  echo "Energy minimization done of $d cycle"
  echo "Copying to OutboundTransfer"
  mkdir ../../Transfer/${d%?}
  cp -r ../ENMIN ../../Transfer/${d%?}
  echo "Copied"

  cd ../../
done

문제는 배선에 있습니다 cp -r ../Transfer/${d%?}/ENMIN/ ./. 배선이 제대로 작동하지 않습니다. 스크립트는 이 줄을 넘지 않습니다. 파일을 복사하면 그게 전부입니다. 생산적인 작업을 중단합니다. "변경된 디렉토리"를 로그에 인쇄하고 그 외에는 아무것도 인쇄하지 않습니다.

두 가지 이상한 점: (1) "cp"(vi 내부)는 다른 명령과 색상이 다릅니다. (2) 스큐를 확인하면 작업이 실행 중인 것처럼 보이지만 실제로는 아무 일도 일어나지 않습니다. in)과 동일한 루프입니다.

해당 디렉토리 구조는 다음과 같습니다(트리 출력).

|-- lambda.00
|-- lambda.01
|-- lambda.02
|-- lambda.03
|-- lambda.04
|-- lambda.05
|-- lambda.06
|-- lambda.07
|-- lambda.08
|-- lambda.09
|-- lambda.10
|-- lambda.11
|-- lambda.12
|-- lambda.13
|-- lambda.14
|-- lambda.15
|-- lambda.16
|-- lambda.17
|-- lambda.18
|-- lambda.19
|-- lambda.20
|-- lambda.21
|-- lambda.22
|-- lambda.23
|-- lambda.24
|-- lambda.25
|-- lambda.26
|-- lambda.27
|-- lambda.28
|-- lambda.29
`-- Transfer
    |-- lambda.00
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.01
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.02
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.03
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.04
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.05
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.06
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.07
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.08
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.09
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.10
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.11
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.12
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.13
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.14
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.15
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.16
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.17
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.18
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.19
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.20
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.21
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.22
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.23
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.24
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.25
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.26
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.27
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    |-- lambda.28
    |   `-- ENMIN
    |       |-- enmin.tpr
    |       `-- mdout.mdp
    `-- lambda.29
        `-- ENMIN
            |-- enmin.tpr
            `-- mdout.mdp

이 클러스터에 대한 통제력은 제한적입니다. 이 스크립트를 작동시키려면 어떤 옵션이 있어야 합니까?

답변1

${d%?}구성은 예를 들어 POSIX 셸에서는 작동하지 않습니다 sh. 운영 체제에 따라 sh간단한 POSIX 셸 dash(예: Debian 또는 Ubuntu) 을 사용하거나 bashPOSIX 모드에서 실행될 수 있습니다. 두 경우 모두 ${d%?}이해되지 않으므로 스크립트가 손상될 가능성이 높습니다.

간단한 해결책은 #!/bin/bash. 그러나 스크립트도 불필요하게 복잡해 보입니다. 한편으로는 ${d%?}디렉토리 이름에서 후행 슬래시를 제거하는 것만으로 문제가 되지만 전혀 소용이 없습니다.

$ d="bar/"
$ cd $d
$ pwd
/home/terdon/foo/bar

디렉터리 이름 끝에 하나 이상의 슬래시가 있어도 괜찮습니다. 이 cd bar작업 을 수행 cd bar/하거나 cd bar//////////.

cd즉, 처음에는 필요하지 않으며 아무런 이유 없이 복잡성 계층을 추가할 뿐입니다. 다음은 스크립트의 단순화된 버전입니다.

#!/bin/bash
for d in lambda.*/
do

  mv Transfer/"$d"/ENMIN/  "$d"
  echo "Transferred"
  ( ## open a subshell so the cd only hapens in the subshell
    ## and doesn't affect the script
    cd "$d"/ENMIN/ && 
      time mpirun -np $SLURM_NTASKS gmx_mpi mdrun -v -stepout 1000 -s enmin.tpr -deffnm enmin
  )
  echo "Energy minimization done of $d cycle"
  echo "Copying to OutboundTransfer"
  mkdir Transfer/"$d"
  cp -r "$d"/ENMIN Transfer/"$d"
  echo "Copied"
done

이것이 어떻게 작동하는지 모르겠지만 sbatch귀하의 설명에 따르면 아마도 스크립트를 실행 sh하고 shebang을 무시하는 것처럼 들립니다. 위의 버전을 시도 sbatch bash MyScript.sh하거나 간단히 시도해 볼 수도 있습니다. 모든 sh 스타일 쉘에 이식 가능해야 합니다. 어쨌든 유일한 문제는 그것이 ${d%?}기 때문에 제거하면 모든 문제가 해결됩니다.

관련 정보