С &&
оператором между командами каждая команда выполняется последовательно, и если какая-либо команда не выполняется (т.е. возвращает ненулевой статус), последующие команды не выполняются.
Если вы хотите продолжать, несмотря ни на что, используйте ;
(или новую строку, что эквивалентно) вместо &&
. Здесь вам нужно выполнить одну команду, и, если она успешна, выполнить еще несколько команд, независимо от того, успешно они или нет. Один из способов добиться этого - поместить эти команды в группу фигурных скобок (просто 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
…
В качестве альтернативы, напишите команду, которая должна завершиться успешно: проверьте, если /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
. Вы написали: «запустите bash в chroot. Когда выйдет Баш, беги source
и export
». Это, вероятно, не то, что вы имели в виду. Чтение /etc/profile
можно сделать, сделав bash оболочкой входа в систему. Возможным способом установки PS1
может быть установка его перед запуском bash, но это не сработает, если /etc/profile
переопределит его, что является распространенным явлением. Лучший способ заключается в наборе PS1
в ~/.bashrc
при работе в изолированном окружении ( .bashrc
не.profile
).
chroot . bash --login
Debian использует следующий код для установки 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\$ '
В качестве альтернативы вместо приглашения используйте переменную среды: run
CHROOT_LOCATION=$PWD chroot bash --login
и вставьте это в ~/.bashrc
или /etc/bash.bashrc
:
if [ -n "$CHROOT_LOCATION" ]; then PS1="($CHROOT_LOCATION)$PS1"; fi
;
. Просто поместите каждую команду в отдельную строку, но вы также должны избавиться отset -e
. Если вас не волнует сбой команды, зачем вообще использоватьset -e
? (Я знаю вопрос, заданный для одной строки, но это не имеет смысла в сценарии).Поместите команду в скобки - (), чтобы вы вернулись в текущий каталог, или cd - в конце. Если вы поместите это в файл и запустите его: sh ./my_script.sh, он запустит команды в измененном каталоге.
В баш
приведет к остановке скрипта при первом сбое. Поскольку вы установили + e, я бы предположил, что вы хотите, чтобы скрипт продолжал работать в случае сбоя команды.
источник