Bir dizine cd ve birçok komut yürütmek


10

Aşağıdaki senaryom var.

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

Burada yapmaya çalıştığım şey bir dizine geçmek /mnt/gentoove birkaç komut yürütmektir. Bu, yollardan hiçbiri monte edilmediğinde ilk kez çalışır. Ancak, bazı yollarda montaj başarıyla gerçekleştirildikten sonra çalıştırırsam, devam etmez ve ilk hatada durur. 'Zaten monte edilmiş' hatası nedeniyle montaj başarısız olsa bile tüm komutların yürütülmesini istiyorum. Bunu nasıl yapabilirim?

Ayrıca, tüm bu komutları tek bir satırda birleştirmekten daha iyi bir yol var mı?

Yanıtlar:


8

İle &&herhangi bir komut (örneğin sıfır olmayan bir durum döner) başarısız olursa komutları arasında operatör, dizideki her komutu çalıştırır, ve, takip eden komutlar çalıştırılmaz.

Ne olursa olsun devam etmek istiyorsanız ;, yerine (veya eşdeğer bir yeni satır) kullanın &&. Burada, bir komutu yürütmeniz gerekir ve başarılı olursa, başarılı olsun ya da olmasın, birkaç komut daha yürütün. Bunu başarmanın bir yolu, bu komutları bir küme ayracı grubuna koymaktır (sadece cd … && mount1; mount2işe yaramaz çünkü bu , öncelik nedeniyle başarılı mount2olup olmadığını yürütür cd).

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

Alternatif olarak, komut dosyasından çıkın veya cdbaşarısız olursa işlevden dönün .

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

Alternatif olarak, altında çalıştırın set -eve || truebaşarısız olabilecek komutların arkasına koyun (“veya devam et”).

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

Alternatif olarak, başarılı olması gereken bir komut yazın: /procönceden takılmış olup olmadığını test edin .

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

Aradığın başka bir sorunun daha var chroot. Şöyle yazdınız: “krootta bash çalıştırın. Bash çıkınca koş sourceve export. ” Muhtemelen demek istediğin bu değil. Okuma /etc/profile, bash'ı bir giriş kabuğu haline getirerek yapılabilir. Ayarlamanın olası bir yolu, PS1bash'ı çalıştırmadan önce ayarlamak olabilir, ancak /etc/profilegeçersiz kılınırsa işe yaramaz , bu da yaygındır. Daha iyi bir yol kümesine olduğu PS1içinde ~/.bashrc bir chroot içinde çalışan eğer ( .bashrcdeğil.profile ).

chroot . bash --login

Debian setine aşağıdaki kodu kullanan PS1içinde /etc/bash.bashrciçeriğine dayalı /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\$ '

Alternatif olarak, bilgi istemi için bunun yerine bir ortam değişkeni kullanın: run

CHROOT_LOCATION=$PWD chroot bash --login

ve bunu ~/.bashrcveya /etc/bash.bashrc:

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

6

&&Bu durumda ayırıcı 'sadece son komutu başarılı olup olmadığını devam' diyor. Eğer kullanırsanız ;yerine, komutları sonuçların dizisi bakılmaksızın içinde çalıştırır.

Bu bir cron işi veya stderr'a yazılan şeylere duyarlı başka bir şeyse, hataları yeniden yönlendirmeniz gerektiğini unutmayın /dev/null.


Kullanmanıza bile gerek yok ;. Sadece her komutu kendi satırına koyun, ama aynı zamanda set -e. Komut hatası ile ilgilenmiyorsanız, neden kullanıyorsunuz set -e? (Sorunun bir satır istediğini biliyorum, ancak bu bir senaryoda anlamsız).
camh

Muhtemelen, bir komut dosyası değildir ve PS1 ayarları olduğundan kaynaklanmalıdır (o-bang hattına sahip olmak mantıklı değildir).
Stéphane Chazelas

0

Komutu (-) köşeli parantez içine alın, böylece geçerli dizine veya cd - sonuna dönün. Bunu bir dosyaya koyar ve çalıştırırsanız: sh ./my_script.sh dizine değiştirilen komutları çalıştırır.

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

Bash

set -e 

betiğin ilk hatada çalışmasının durmasına neden olur. + E ayarladığınız için, bir komut başarısız olursa komut dosyasının çalışmaya devam etmesini istediğinizi varsayarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.