디렉토리에 cd하고 많은 명령을 실행


10

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

#!/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몇 가지 명령을 실행하는 것입니다. 경로가 마운트되지 않은 경우 처음에는 정상적으로 작동합니다. 그러나 일부 경로에서 마운트가 성공적으로 수행 된 후 실행하면 첫 번째 실패에서 계속되지 않고 중지됩니다. '이미 마운트 됨'오류로 인해 마운트에 실패한 경우에도 모든 명령을 실행하고 싶습니다. 어떻게해야합니까?

또한이 모든 명령을 한 줄로 결합하는 것보다 더 좋은 방법이 있습니까?

답변:


8

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

무슨 일이 있어도 계속 가고 싶다면 ;대신 (또는 줄 바꿈)을 사용하십시오 &&. 여기서 하나의 명령을 실행해야하며 성공하면 명령의 성공 여부에 관계없이 몇 가지 명령을 더 실행하십시오. 이를 달성하는 한 가지 방법은 이러한 명령을 중괄호 그룹에 넣는 cd … && mount1; mount2것입니다 ( 우선 순위로 인해 성공 mount2했는지 여부를 실행하기 때문에 작동 하지 않습니다 cd).

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

또는 성공해야하는 명령을 작성하십시오. test if /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가 종료되면 sourceand를 실행하십시오 export.” 그것은 아마도 당신이 의도 한 것이 아닙니다. /etc/profilebash를 로그인 쉘로 만들어서 읽을 수 있습니다. 가능한 설정 방법은 PS1bash를 실행하기 전에 설정하는 것일 수 있지만, 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

6

&&이 경우 구분은 '마지막 명령이 성공하면 계속'말하고있다. ;대신 사용하면 결과에 관계없이 명령이 순서대로 실행됩니다.

이 작업이 cron 작업이거나 stderr에 작성되는 항목에 민감한 다른 경우 오류를로 리디렉션해야합니다 /dev/null.


당신은 사용할 필요가 없습니다 ;. 각 명령을 자체 행에 두십시오. 그러나를 제거해야합니다 set -e. 명령 실패에 신경 쓰지 않는다면 왜 사용 set -e합니까? (질문은 한 줄을 요구했지만 스크립트 내에서는 의미가 없습니다.)
camh

아마도 이것은 스크립트가 아니며 PS1 설정이기 때문에 소스가되어야합니다 (she-bang 라인을 갖는 것은 의미가 없지만).
Stéphane Chazelas

0

명령을 대괄호 (-)로 묶어 현재 디렉토리로 돌아가거나 끝에 cd를 넣으십시오. 이것을 파일에 넣고 그것을 실행하면 : sh ./my_script.sh 명령은 변경된 디렉토리에서 명령을 실행합니다.

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

bash에서

set -e 

첫 번째 실패에서 스크립트 실행이 중지됩니다. + e를 설정했기 때문에 명령이 실패하면 스크립트가 계속 실행되기를 원한다고 가정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.