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

З &&оператором між командами кожна команда запускається послідовно, і якщо будь-яка команда не працює (тобто повертає ненульовий статус), наступні команди не виконуються.

Якщо ви хочете продовжувати роботу незалежно від того, використовуйте ;(або новий рядок, що еквівалентно) замість &&. Тут потрібно виконати одну команду, і якщо це вдасться, виконати ще кілька команд, успішні вони чи ні. Один із способів досягти цього - помістити ці команди всередині групи брекетів (просто 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. Ви писали: «Запускай баш у 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\$ '

Крім того, для підказки, замість цього використовуйте змінну середовища: запустити

CHROOT_LOCATION=$PWD chroot bash --login

і помістити це в ~/.bashrcабо /etc/bash.bashrc:

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

6

У &&цьому випадку роздільник говорить "продовжуйте лише тоді, коли остання команда була успішною". Якщо ви використовуєте ;замість цього, команди виконуватимуться в послідовності незалежно від результатів.

Зауважте, що якщо це робота з крон або щось інше, чутливе до того, що речі записуються в stderr, вам потрібно буде перенаправити помилки на /dev/null.


Вам навіть не потрібно користуватися ;. Просто поставте кожну команду у свій рядок, але ви також повинні позбутися від set -e. Якщо вас не хвилює збій команди, навіщо взагалі використовувати set -e? (Я знаю, що питання задавали один рядок, але це не має сенсу в сценарії).
camh

Імовірно, це не сценарій і призначений для отримання (хоч мати лінію she-bang не має сенсу), оскільки це налаштування PS1.
Стефан Шазелас

0

Поставте команду в дужки - (), щоб ви повернулися до поточного каталогу, або cd - в кінці. Якщо ви помістите це у файл та запустіть його: sh ./my_script.sh, він запустить команди у каталог, що змінився.

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

В баш

set -e 

призведе до припинення роботи сценарію при першій відмові. Оскільки ви встановили + e, я вважаю, що ви хотіли, щоб сценарій продовжував працювати, якщо команда не працює.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.