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 cp
Nachricht benötigt, ist das Neukompilieren des Programms aus dem Quellcode die beste Lösung. Ein etwas sinnvollerer Ansatz wäre jedoch, printf
vorzugsweise Ihre eigene Nachricht über zu schreiben, anstatt zu versuchen, cp
die Ausgabe abzufangen, und Benutzerauswahlen über select
den Dialog zu handhaben. Wenn Sie außerdem Fehlermeldungen ausgeben möchten, sollten diese in stderr
den 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 cp
durch 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