cd ke direktori dan jalankan banyak perintah


10

Saya memiliki skrip berikut.

#!/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" 

Apa yang saya coba capai di sini adalah mengubah ke direktori /mnt/gentoodan menjalankan beberapa perintah. Ini berfungsi baik pertama kali ketika tidak ada jalur yang dipasang. Tetapi jika saya menjalankannya setelah pemasangan telah berhasil dilakukan pada beberapa jalur, itu tidak melanjutkan dan berhenti pada kegagalan pertama. Saya ingin semua perintah dieksekusi walaupun mount gagal karena kesalahan 'sudah terpasang'. Bagaimana saya bisa melakukan ini?

Juga adakah cara yang lebih baik daripada menggabungkan semua perintah ini menjadi satu baris?

Jawaban:


8

Dengan &&operator di antara perintah, setiap perintah berjalan secara berurutan, dan jika ada perintah gagal (yaitu mengembalikan status bukan nol), perintah selanjutnya tidak dijalankan.

Jika Anda ingin terus berjalan apa pun, gunakan ;(atau baris baru, yang setara) &&. Di sini, Anda perlu menjalankan satu perintah, dan jika berhasil, jalankan beberapa perintah lagi apakah mereka berhasil atau tidak. Salah satu cara untuk mencapai ini adalah dengan menempatkan perintah-perintah ini di dalam kelompok penyangga ( cd … && mount1; mount2tidak akan berfungsi karena ini dijalankan mount2apakah cdberhasil atau tidak karena didahulukan).

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

Atau, keluar dari skrip atau kembali dari fungsi jika cdgagal.

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

Atau, jalankan di bawah set -e, dan masukkan || true("atau tetap pergi") setelah perintah yang mungkin gagal.

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

Atau, tulis perintah yang harus berhasil: tes jika /procdan seterusnya sudah terpasang.

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

Anda memiliki masalah lain di mana Anda menelepon chroot. Anda telah menulis: “jalankan bash di chroot. Saat bash keluar, jalankan sourcedan export. " Mungkin itu bukan yang Anda maksudkan. Membaca /etc/profiledapat dilakukan dengan membuat bash shell login. Cara yang mungkin untuk ditetapkan PS1adalah mengaturnya sebelum menjalankan bash, tetapi itu tidak akan berhasil jika /etc/profilemenimpanya, yang merupakan hal biasa. Cara yang lebih baik adalah untuk set PS1di ~/.bashrc jika berjalan di dalam chroot ( .bashrc, bukan.profile ).

chroot . bash --login

Debian menggunakan kode berikut untuk set PS1di /etc/bash.bashrcberdasarkan isi /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\$ '

Atau, untuk prompt, gunakan variabel lingkungan sebagai gantinya: jalankan

CHROOT_LOCATION=$PWD chroot bash --login

dan letakkan ini di ~/.bashrcatau /etc/bash.bashrc:

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

6

The &&pemisah dalam hal ini adalah mengatakan 'hanya melanjutkan jika perintah terakhir berhasil'. Jika Anda menggunakan ;sebagai gantinya, perintah akan dijalankan berurutan terlepas dari hasilnya.

Perhatikan bahwa jika ini adalah pekerjaan cron atau sesuatu yang sensitif terhadap hal-hal yang ditulis ke stderr, Anda harus mengarahkan kesalahan ke /dev/null.


Anda bahkan tidak perlu menggunakan ;. Hanya menempatkan setiap perintah pada barisnya sendiri, tetapi Anda juga harus menyingkirkan set -e. Jika Anda tidak peduli dengan kegagalan perintah, mengapa menggunakan set -e? (Saya tahu pertanyaan yang diajukan untuk satu baris, tetapi itu tidak masuk akal dalam naskah).
camh

Agaknya, itu bukan skrip dan dimaksudkan untuk bersumber (meskipun memiliki garis she-bang tidak masuk akal) karena pengaturan PS1.
Stéphane Chazelas

0

Masukkan perintah dalam tanda kurung - (), sehingga Anda kembali ke direktori saat ini, atau cd - di akhir. Jika Anda meletakkan ini di file dan menjalankannya: sh ./my_script.sh itu akan menjalankan perintah di direktori yang diubah.

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

Di bash

set -e 

akan menyebabkan skrip berhenti berjalan pada kegagalan pertama. Karena Anda telah menyetel + e saya akan menganggap Anda ingin skrip tetap berjalan jika perintah gagal.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.