С &&оператором между командами каждая команда выполняется последовательно, и если какая-либо команда не выполняется (т.е. возвращает ненулевой статус), последующие команды не выполняются.
Если вы хотите продолжать, несмотря ни на что, используйте ;(или новую строку, что эквивалентно) вместо &&. Здесь вам нужно выполнить одну команду, и, если она успешна, выполнить еще несколько команд, независимо от того, успешно они или нет. Один из способов добиться этого - поместить эти команды в группу фигурных скобок (просто 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? (Я знаю вопрос, заданный для одной строки, но это не имеет смысла в сценарии).