cd para um diretório e execute muitos comandos

7

Eu tenho o seguinte script.

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

O que estou tentando realizar aqui é mudar para um diretório /mnt/gentoo e executar alguns comandos. Isso funciona bem na primeira vez em que nenhum dos caminhos foi montado. Mas se eu o executar após a montagem ter sido executada com sucesso em alguns caminhos, ele não continuará e parará na primeira falha. Eu quero que todos os comandos sejam executados mesmo se a montagem estiver falhando devido ao erro 'já montado'. Como posso fazer isso?

Existe também uma maneira melhor de combinar todos esses comandos em uma linha?

    
por Dilawar 13.03.2013 / 09:03

3 respostas

6

Com o operador && entre comandos, cada comando é executado em seqüência e, se algum comando falhar (isto é, retornar um status diferente de zero), os comandos subseqüentes não serão executados.

Se você quiser continuar, não importa o que, use ; (ou uma nova linha, que é equivalente) em vez de && . Aqui, você precisa executar um comando e, se for bem-sucedido, executar mais alguns comandos, sejam eles bem-sucedidos ou não. Uma maneira de conseguir isso é colocar esses comandos dentro de um grupo de chaves (apenas cd … && mount1; mount2 não funcionará porque isso executa mount2 se cd é ou não bem-sucedido devido à precedência).

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

Como alternativa, saia do script ou retorne da função se cd falhar.

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

Como alternativa, execute em set -e e coloque || true ("ou continue assim mesmo") depois de comandos que possam falhar.

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

Como alternativa, escreva um comando que deve ser bem-sucedido: teste se /proc e assim por diante já estiverem montados.

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

Você tem outro problema em que você chama chroot . Você escreveu: “execute o bash no chroot. Quando o bash sair, execute source e export . ”Isso provavelmente não é o que você quis dizer. Lendo /etc/profile pode ser feito fazendo bash um shell de login. Uma maneira possível de definir PS1 pode ser configurá-lo antes de executar o bash, mas isso não funcionará se /etc/profile o substituir, o que é comum. Uma maneira melhor é definir PS1 em ~/.bashrc se executado dentro de um chroot ( .bashrc , não .profile ).

chroot . bash --login

O Debian usa o seguinte código para definir PS1 em /etc/bash.bashrc com base no conteúdo de /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\$ '

Como alternativa, para o prompt, use uma variável de ambiente: execute

CHROOT_LOCATION=$PWD chroot bash --login

e coloque isso em ~/.bashrc ou /etc/bash.bashrc :

if [ -n "$CHROOT_LOCATION" ]; then PS1="($CHROOT_LOCATION)$PS1"; fi
    
por 13.03.2013 / 22:34
6

O separador && neste caso está dizendo 'continue somente se o último comando foi bem-sucedido'. Se você usar ; , os comandos serão executados em sequência, independentemente dos resultados.

Note que se este for um trabalho do cron ou algo mais sensível ao material sendo gravado no stderr, você precisará redirecionar os erros para /dev/null .

    
por 13.03.2013 / 09:24
0

Coloque o comando entre colchetes - (), para que você retorne ao diretório atual, ou cd - no final. Se você colocar isso em um arquivo e executá-lo: sh. / My_script.sh ele irá executar os comandos no diretório alterado.

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

No bash

set -e 

fará com que o script pare de funcionar na primeira falha. Porque você definiu + e eu suponho que você queria que o script continuasse em execução se um comando falhar.

    
por 13.03.2013 / 11:03

Tags