디렉토리로 CD를 이동하고 많은 명령을 실행합니다.

디렉토리로 CD를 이동하고 많은 명령을 실행합니다.

다음 스크립트가 있습니다.

#!/bin/bash
mount /dev/sda6 /mnt/gentoo
set +e
cd /mnt/gentoo && mount -t proc none /mnt/gentoo/proc \
 && mount --rbind /dev /mnt/gentoo/dev \
 && mount --rbind /sys /mnt/gentoo/sys \
 && chroot /mnt/gentoo /bin/bash \
 && source /etc/profile  \
 && export PS1="(chroot)$PS1" 

여기서 달성하려는 작업은 디렉터리를 변경 /mnt/gentoo하고 몇 가지 명령을 실행하는 것입니다. 경로가 마운트되지 않은 처음에는 제대로 작동합니다. 그러나 특정 경로에서 성공적으로 설치한 후 실행하면 계속되지 않고 첫 번째 실패 시 중지됩니다. "이미 설치됨" 오류로 인해 설치가 실패하더라도 모든 명령이 실행되기를 원합니다. 어떻게 해야 하나요?

이 모든 명령을 함께 결합하는 것보다 더 좋은 방법은 무엇일까요?

답변1

명령 사이에 연산자를 사용하면 &&각 명령이 순서대로 실행되며 명령이 실패하면(즉, 0이 아닌 상태를 반환하는 경우) 후속 명령이 실행되지 않습니다.

어쨌든 계속하려면 ;대신 (또는 이에 상응하는 줄 바꿈)을 사용하십시오 &&. 여기서 명령을 실행해야 하며, 성공하면 성공 또는 실패에 관계없이 몇 가지 명령을 더 실행해야 합니다. 이를 달성하는 한 가지 방법은 이러한 명령을 중괄호 그룹에 넣는 것입니다( 우선 순위로 인해 성공 여부에 관계없이 명령이 실행되기 cd … && mount1; mount2때문에 작동하지 않습니다 ).mount2cd

cd /mnt/gentoo && {
  mount -t proc none /mnt/gentoo/proc
  mount --rbind /dev /mnt/gentoo/dev
  mount --rbind /sys /mnt/gentoo/sys
}

또는 실패하면 스크립트를 종료하거나 함수에서 돌아갑니다 cd.

cd /mnt/gentoo || exit $?
mount -t proc none /mnt/gentoo/proc

또는 아래에서 실행 set -e하고 || true실패할 수 있는 명령 뒤에 넣습니다("또는 계속 진행").

set -e
cd /mnt/gentoo
mount -t proc none /mnt/gentoo/proc || true

또는 성공해야 하는 명령을 작성합니다. /proc설치되었는지 테스트하는 등의 작업을 수행합니다.

mount_if_needed () {
  eval "mount_point=${\$#}"
  awk -v target="$mount_point" '$2 == target {exit(0)} END {exit(1)}' </proc/mounts ||
  mount "$@"
}
set -e
cd /mnt/gentoo
mount_if_needed -t proc none /mnt/gentoo/proc

에 전화하시면 또 다른 문제가 발생합니다 chroot. "chroot에서 bash를 실행하세요. bash가 종료되면 실행 source하고 ." 라고 작성하셨습니다. export아마도 그런 뜻이 아닐 것입니다. /etc/profilebash를 로그인 쉘로 설정하여 읽기를 수행할 수 있습니다. 이를 설정하는 한 가지 가능한 방법 PS1은 bash를 실행하기 전에 설정하는 것이지만, 덮어쓰면 작동하지 않는 /etc/profile것이 일반적입니다. 더 나은 접근 방식 PS1~/.bashrc chroot 내에서 실행 중인 경우(.bashrc, 아니요.profile).

chroot . bash --login

데비안은 다음 코드를 사용하여 다음 PS1과 같이 설정합니다./etc/bash.bashrc/etc/debian_chroot

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

또는 프롬프트의 경우 대신 환경 변수를 사용하십시오.

CHROOT_LOCATION=$PWD chroot bash --login

그것을 넣거나 ~/.bashrc:/etc/bash.bashrc

if [ -n "$CHROOT_LOCATION" ]; then PS1="($CHROOT_LOCATION)$PS1"; fi

답변2

이 예에서 구분 기호는 &&"마지막 명령이 성공한 경우에만 계속"을 의미합니다. 대신 사용 하면 ;결과에 관계없이 명령이 순차적으로 실행됩니다.

cron 작업이거나 stderr에 기록된 내용에 민감한 다른 작업인 경우 오류를 로 리디렉션해야 합니다 /dev/null.

답변3

현재 디렉터리로 돌아가려면 명령을 대괄호 - ()로 묶거나 끝에 cd -로 묶습니다. 이것을 파일에 넣고 실행하면: sh ./my_script.sh 변경된 디렉토리에서 명령이 실행됩니다.

cd  /mnt/gentoo
mount -t proc none /mnt/gentoo/proc
...
cd - 

배쉬에서

set -e 

첫 번째 실패 시 스크립트 실행이 중지됩니다. +e를 설정했으므로 명령이 실패하더라도 스크립트가 계속 실행되기를 원한다고 가정합니다.

관련 정보