Beenden Sie einen Bash-Befehl in einem Skript, ohne das Skript zu beenden

Beenden Sie einen Bash-Befehl in einem Skript, ohne das Skript zu beenden

Ich arbeite an einem Skript, das einen Hausaufgabenordner (die Quelldateien) durchsucht und, wenn der Ordner existiert, nach einem Zielordner sucht. Wenn dieser Ordner nicht existiert, kopiert es die Quelle in das Ziel.

Wenn das Ziel vorhanden ist, wird versucht, die Datei von der Quelle zum Ziel zu kopieren. Der Benutzer wird vorher dazu aufgefordert, damit bereits von diesem Benutzer geleistete Arbeit nicht überschrieben wird.

Die Ausgabe des Befehls muss in einem bestimmten Format vorliegen, daher kann ich die Standardausgabe des Befehls nicht so verwenden, wie sie ist. Ich muss sie erfassen und neu formatieren. Dann nehme ich die Eingabe (d. h. j/n) in einem bestimmten Format entgegen.

Der Vorteil dabei ist, dass der Kopierbefehl bereits hilfreiche Dinge tut. Wenn eine Datei nicht existiert, wird sie kopiert.

Wenn eine Datei oder mehrere Dateien bereits vorhanden sind, wird wiederholt gefragt: „Überschreiben, j/n?“ Mit diesem Fall versuche ich umzugehen.

Ich habe es so weit geschafft, die Ausgabe des Kopierbefehls in einer Variablen zu erfassen und ihre normale Ausgabe zu unterdrücken, sodass ich ihre Ausgabe neu formatieren und dieses Format an den Benutzer zurückgeben kann.

Als nächstes denke ich, dass ich den Befehl beenden (oder auf andere Weise stoppen) muss, dann die Ausgabe in meinem gewünschten Format drucken und den Befehl erneut aufrufen muss. Beim zweiten Mal kann ich die Eingabeaufforderung „y/N“ in meinem gewünschten Format ausgeben und der Benutzer kann dann seine Wahl treffen. Trotz Suche konnte ich nicht herausfinden/verstehen, wie ich den Befehl beenden oder auf andere Weise stoppen kann, nachdem er aufgerufen wurde. Ich habe „kill“ und verschiedene Versuche mit SIGINT ausprobiert. Entweder verstehe ich einfach nicht, wie man diese verwendet, oder sie sind nicht die richtige Wahl. Wenn ich versuche, sie zu verwenden, erhalte ich einen Syntaxfehler.

Hier ist mein Code:

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

Antwort1

Wenn man wirklich wirklich wirklich eine benutzerdefinierte cpNachricht benötigt, ist das Neukompilieren des Programms aus dem Quellcode die beste Lösung. Ein etwas sinnvollerer Ansatz wäre jedoch, printfvorzugsweise Ihre eigene Nachricht über zu schreiben, anstatt zu versuchen, cpdie Ausgabe abzufangen, und Benutzerauswahlen über selectden Dialog zu handhaben. Wenn Sie außerdem Fehlermeldungen ausgeben möchten, sollten diese in stderrden Stream gehen. Schließlich ist es unnötig und Sie können stattdessen einfach glob *.*verwenden .*

Unten sehen Sie das Skript mit einigen Änderungen. Beachten Sie, dass Sie #cp "$item" "$HOMEWORKDIRECTORY"die Zeile auskommentieren müssen, damit das eigentliche Kopieren erfolgen kann. Ersetzen Sie es zu Testzwecken cpdurch echo„first“.

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

verwandte Informationen