2016-12-20 5 views
0

Ich versuche, ein Shell-Skript zu schreiben, um eine Datei basierend auf Benutzerantwort zu kopieren. Ein Beispiel dafür, was ich zu tun versucht:Bash - Antwort zum Kopieren von Dateien oder Verzeichnis lesen

#!/bin/bash 
echo "What is the name of the user?: " 
read RESPONSE 
cp /home/$RESPONSE/file.txt /home/$RESPONSE/backup/file_backup.txt 

jedoch mein Kopierbefehl scheint nicht richtig die Lese Variable zu akzeptieren. Was mache ich falsch?

+2

Was * genau * ist falsch? Wenn der Benutzername ein Leerzeichen oder einen umgekehrten Schrägstrich enthält oder als ein Glob ausgewertet werden kann, sind die Fehler ziemlich offensichtlich - aber Sie müssen genauer auf das * genaue * Verhalten achten. "Scheint nicht zu akzeptieren" - woher weißt du das? Was ist die genaue Eingabe und der genaue Fehler in der Ausgabe? –

+1

Sie sollten 'bash -x yourscript' ausführen, um es mit der Protokollierung für aufgerufene Befehle auszuführen. Führe es auch durch http://shellcheck.net/ und repariere, was das findet (das ist immer ein guter Ratschlag, bevor du hier Shell-Fragen stellst). –

+0

Verwenden Sie auch keine Großbuchstaben für Ihre eigenen Variablen! Großbuchstabennamen werden von Variablen verwendet, die eine Bedeutung für das Betriebssystem oder die Shell haben. Bei Verwendung von Kleinbuchstaben wird vermieden, dass versehentlich auf diese zugegriffen wird. Siehe [das entsprechende Normendokument] (http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html), Absatz 4 (ja, es werden Umgebungsvariablen diskutiert, aber das Setzen einer regulären Shell-Variablen überschreibt ein ähnliches benannte Umgebungsvariable, so gilt die Konvention in beiden Orten). –

Antwort

0

Ich habe das Problem herausgefunden. Ich hatte einige Befehle dazwischen und hatte dann einen zweiten Read-Befehl, der nicht benötigt wurde. Mit anderen Worten, als ein Beispiel, ich hatte dies:

#!/bin/bash 
echo "What is the name of the user?: " 
read RESPONSE 
rsync -a /home/$RESPONSE /backup 
read RESPONSE 
cp /home/$RESPONSE/file.txt /home/$RESPONSE/backup/file_backup.txt 

Auch @ GeorgeVasiliou hatte Recht, ich auch benötigt, um es in Anführungszeichen enthalten. So was funktioniert ist:

#!/bin/bash 
echo "What is the name of the user?: " 
read response 
rsync -a "/home/$response/" /backup 
cp "/home/$response/file.txt" "/home/$response/backup/file_backup.txt" 
+0

Sie würden wahrscheinlich besser dran sein, indem Sie Ihr Skript überprüfen, ob der Benutzer und der Sicherungsordner vorhanden sind oder nicht, bevor Sie das Skript vollständig ausführen. Siehe meine Antwort. –

+0

Stellen Sie in Zukunft sicher, dass Ihr vereinfachter Code in Ihrer Frage das gleiche Problem hat wie das echte Programm, für das Sie einen Reproduzierer erstellen möchten. –

0

Der folgende Code erreicht, was Sie wollen. Es prüft auch, ob der Benutzer existiert und ob der Benutzer einen/backup/Ordner erstellt hat, bevor er versucht, die Datei zu speichern (wenn kein Benutzer existiert, sollte/home/user/... ebenfalls nicht existieren und der Skript würde fehlschlagen).

#!/bin/bash 

echo "What is the name of the user?: " 
read response 
checkuser1="$(getent passwd | cut -d: -f1 | grep -si "$response")" 
if [ -z "$checkuser1" ]; then echo "No user with this name has been located!"; exit; fi 
if [ ! -d /home/"$response"/backup/ ]; then echo "This user has not created the /home/"$response"/backup/ folder yet!"; exit; fi 
cp /home/"$response"/file.txt /home/"$response"/backup/file_backup.txt 
exit 

bearbeiten: Der Code oben bearbeitet wurde einige Verbesserungen hinzuzufügen.

+0

Schön. Ich mag das. Vielen Dank. – t3kg33k

+0

Ich würde vorschlagen, 'getent passwd' zu verwenden, anstatt direkt auf'/etc/passwd' zu verweisen - auf diese Weise werden Systeme unterstützt, die NIS, LDAP oder andere Verzeichnisdienste verwenden und nicht auf lokale Dateiauthentifizierung beschränkt sind nur. Sie können auch explizit einen Exit-Status ungleich Null für die Fehlerfälle angeben. (Im Gegensatz dazu ist im normalen Fall das Standardverhalten des Beendens mit dem Status des letzten Befehls - das von 'cp' - wahrscheinlich das Richtige; durch das Einfügen eines expliziten' exit 0' haben Sie ein erfolgreicher Exit-Status, auch wenn 'cp' fehlgeschlagen ist. –

+0

Danke Charles! Ich liebe 'getent', ich hatte noch nie davon gehört. Auch sollte der finale 'exit' nicht auf Null gesetzt werden - ich habe viel für sehr Anfänger entwickelt (Anfänger wie kann man nicht doppelt klicken!) Und normalerweise mache ich den Code so leise wie möglich, das war's nur die Gewohnheit, aber regelmäßige 'exit' hier ist viel besser. Ich habe meine Antwort korrigiert. –

Verwandte Themen