sai de um comando bash em um script sem sair do script

6

Estou trabalhando em um script que examina uma pasta de trabalhos de casa (os arquivos de origem) e, se a pasta existir, ela procura uma pasta de destino. Se essa pasta não existir, copia a origem para o destino.

Se o destino existir, ele tentará copiar o arquivo da origem para o destino e, antes disso, avisar o usuário primeiro para que ele não substitua o trabalho já feito por esse usuário.

A saída do comando deve estar em um formato específico, portanto, não posso usar a saída padrão do comando como está. Eu devo capturá-lo e reformatá-lo. Então pegue a entrada (ou seja, y / N) em um formato específico.

O benefício de fazer isso é que o comando de cópia já faz coisas que são úteis. Se um arquivo não existir, ele copia.

Se um arquivo ou vários arquivos já existirem, ele perguntará repetidamente "sobrescrever y / n?" É neste caso que estou tentando lidar.

Eu consegui capturar a saída do comando copy em uma variável e suprimir sua saída normal para que eu possa reformatar sua saída e fazer o eco desse formato de volta para o usuário.

Em seguida, meu pensamento é que preciso matar (ou interromper o comando de alguma forma), imprimir a saída no formato desejado e, em seguida, invocar novamente o comando e, na segunda vez, posso fazer o eco y / N prompt no meu formato desejado e, em seguida, o usuário pode fazer sua escolha. Apesar de pesquisar, não consegui entender como matar ou interromper o comando depois que ele é invocado. Eu tentei matar e várias tentativas de usar o SIGINT. Ou eu simplesmente não entendo como usá-los, ou eles não são a escolha certa. Quando tento usá-los, recebo um erro de sintaxe.

Aqui está o meu código:

#!/bin/bash

USAGE="Usage: ./script2.sh [hw-name]"
EINVALID="Invalid homework: $1"
SOURCEDIRECTORY="$PUBLIC/homework/$1"
HOMEWORKDIRECTORY="$HOME/homework/$1"
COPY="$SOURCEDIRECTORY/*.*"

if [ -z "$1" ]; then
    echo $USAGE
    exit
fi

if [ ! -d "$SOURCEDIRECTORY" ]; then
    echo $EINVALID
    exit
fi

if [ ! -d "$HOMEWORKDIRECTORY" ]; then
    echo "making homework1"
    mkdir -p $HOMEWORKDIRECTORY

copyOutput2="$(eval cp -ir $COPY $HOMEWORKDIRECTORY 2>&1 &stop this
 process somehow)"
echo $copyOutput2 #temporary output for testing
    
por user836747 02.06.2018 / 23:13

1 resposta

4

Se realmente é realmente necessário ter personalizado cp com mensagem personalizada, então recompilar o programa a partir da origem é o caminho a percorrer, mas uma abordagem um pouco mais sensata seria escrever sua própria mensagem via printf de preferência , em vez de tentar interceptar a saída de cp e manipular as opções do usuário por meio do diálogo select . Além disso, se você estiver enviando mensagens de erro, elas devem ir para stderr stream. Finalmente, *.* é desnecessário e você pode usar apenas * glob.

Abaixo está o script com algumas edições. Observe que você precisa descomentar a linha #cp "$item" "$HOMEWORKDIRECTORY" para que a cópia real ocorra. Para fins de teste, substitua cp por echo primeiro.

#!/bin/bash

USAGE="Usage: ./script2.sh [hw-name]"
EINVALID="Invalid homework: $1"
SOURCEDIRECTORY="$PUBLIC/homework/$1"
HOMEWORKDIRECTORY="$HOME/homework/$1"
#COPY="$SOURCEDIRECTORY/*.*"

if [ -z "$1" ]; then
    echo "$USAGE" > /dev/stderr
    exit 1
fi

if [ ! -d "$SOURCEDIRECTORY" ]; then
    echo "$EINVALID" > /dev/stderr
    exit 2
fi

if [ ! -d "$HOMEWORKDIRECTORY" ]; then
    echo "making homework1"
    mkdir -p $HOMEWORKDIRECTORY

for item in "$SOURCEDIRECTORY"/*; do
    skip=true
    if [ -f "$HOMEWORKDIRECTORY"/"${item##*/}" ]; then
        printf "%s already exists in %s.\n" "$item" "$HOMEWORKDIRECTORY"

        select choice in  "overwrite" "skip"; do
            case "$choice" in 
                "overwrite")  echo "Overwriting."  
                              break;;
                "skip") skip=true; break;;
            esac
        done
    fi

    if [ "$skip" = "true" ]; then
        continue
    fi
    echo cp "$item" "$HOMEWORKDIRECTORY"

done
    
por Sergiy Kolodyazhnyy 03.06.2018 / 02:37