cd 到一个目录并执行许多命令

cd 到一个目录并执行许多命令

我有以下脚本。

#!/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并执行一些命令。当没有安装任何路径时,第一次可以正常工作。但是,如果我在某些路径上成功执行安装后运行它,它不会继续并在第一次失败时停止。即使安装由于“已安装”错误而失败,我也希望执行所有命令。我怎样才能做到这一点?

还有比将所有这些命令组合在一起更好的方法吗?

答案1

通过&&命令之间的运算符,每个命令都会按顺序运行,如果任何命令失败(即返回非零状态),则后续命令不会执行。

如果您无论如何都想继续,请使用;(或等效的换行符)而不是&&.这里,你需要执行一个命令,如果成功了,再执行一些命令,不管成功与否。实现此目的的一种方法是将这些命令放在大括号组中(只是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 中运行 bash。当 bash 退出时,运行sourceexport。”这可能不是你的意思。/etc/profile可以通过将 bash 设置为登录 shell 来完成读取。一种可能的设置方法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\$ '

或者,对于提示符,请改用环境变量:运行

CHROOT_LOCATION=$PWD chroot bash --login

并将其放入~/.bashrc/etc/bash.bashrc

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

答案2

本例中的分隔&&符表示“仅当最后一个命令成功时才继续”。如果您;改为使用,命令将按顺序执行,无论结果如何。

请注意,如果这是一个 cron 作业或其他对写入 stderr 的内容敏感的内容,则需要将错误重定向到/dev/null.

答案3

将命令放在括号 - () 中,以便返回当前目录,或者在末尾 cd - 。如果将其放入文件中并运行它: sh ./my_script.sh 它将运行更改为目录中的命令。

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

在bash中

set -e 

将导致脚本在第一次失败时停止运行。因为您已经设置了 +e,所以我假设您希望脚本在命令失败时继续运行。

相关内容