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คุณมีปัญหาที่คุณโทรอีก คุณได้เขียน:“ ใช้ bash ใน chroot เมื่อ bash ออกให้รันsourceและexport” นั่นอาจไม่ใช่สิ่งที่คุณหมายถึง การอ่าน/etc/profileสามารถทำได้โดยการทุบตีเปลือกเข้าสู่ระบบ วิธีที่เป็นไปได้ในการตั้งค่าPS1อาจเป็นการตั้งค่าก่อนที่จะรัน bash แต่วิธีนี้จะไม่ทำงานหาก/etc/profileแทนที่มันซึ่งเป็นเรื่องปกติ วิธีที่ดีกว่าคือการตั้งค่าPS1ใน~/.bashrc ถ้าทำงานภายใน chroot ( .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

6

&&คั่นในกรณีนี้ไม่ว่าจะเป็น 'เพียงดำเนินการต่อหากคำสั่งสุดท้ายก็ประสบความสำเร็จ' หากคุณใช้;แทนคำสั่งจะดำเนินการตามลำดับโดยไม่คำนึงถึงผลลัพธ์

โปรดทราบว่าถ้าเป็นงาน cron หรือสิ่งอื่นที่มีความไวต่อสิ่งที่ถูกเขียนไป stderr /dev/nullคุณจะต้องเปลี่ยนเส้นทางข้อผิดพลาดไป


;คุณไม่จำเป็นต้องแม้กระทั่งการใช้งาน เพียงแค่ใส่แต่ละคำสั่งในบรรทัดของตัวเอง set -eแต่คุณยังต้องได้รับการกำจัด หากคุณไม่สนใจเกี่ยวกับความล้มเหลวของคำสั่งทำไมยังใช้set -e? (ฉันรู้ว่าคำถามถามหนึ่งบรรทัด แต่มันก็ไม่สมเหตุสมผลในสคริปต์)
camh

สันนิษฐานว่ามันไม่ใช่สคริปต์และมีจุดประสงค์เพื่อให้มีแหล่งที่มา (แม้ว่าจะมีบรรทัดที่บางเบาไม่สมเหตุสมผล) เนื่องจากเป็นการตั้งค่า PS1
Stéphane Chazelas

0

วางคำสั่งในวงเล็บ - () เพื่อให้คุณกลับไปยังไดเรกทอรีปัจจุบันหรือ cd - ที่ส่วนท้าย หากคุณวางสิ่งนี้ลงในไฟล์และรันมัน: sh ./my_script.sh มันจะรันคำสั่งในไดเรกทอรีที่ถูกเปลี่ยนเป็น

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

ในทุบตี

set -e 

จะทำให้สคริปต์หยุดทำงานในความล้มเหลวครั้งแรก เนื่องจากคุณได้ตั้งค่า + e ฉันจะถือว่าคุณต้องการให้สคริปต์ทำงานต่อไปหากคำสั่งล้มเหลว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.