Neue ausführbare Datei mit Datensätzen aus einer Datei und Variablen erstellen

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von AnonStar, 10.08.2007.

  1. #1 AnonStar, 10.08.2007
    Zuletzt bearbeitet: 10.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Hallo erstmal allesamt.
    Mein erster Beitrag hier.

    Ich habe in letzter Zeit eigentlich nur Batch-Scripte, HTML etc. geschrieben und nie shells.
    Möchte aber jetzt ein Problem mit einer Shell lösen.

    Ich verwende SuSE Linux 10.2 und habe folgendes Problem:

    Ich benötige oft eine ausführbare Datei, die bestimmte Befehle für einen User ausführt.
    Diese Datei enthält viele Variablen, die vorher festgelegt werden müssen (und in der Datei festgelegt sind) und für jeden User und Anwendung verschieden sind.
    Da ich diese Datei nun mal oft benötige, möchte ich jetzt ein Shell Script schreiben, das per einfacher Benutzerabfrage (read) die Variablen und das Zielverzeichnis abfragt.
    Nun soll dieses shell Script folgendes nach der Benutzerabfrage tun:

    - Die ersten x Zeilen aus der ausführbaren Datei in eine neue Datei nach $VAR_ZIEL_DIR kopieren, dann statt die Zeile mit Variable (nennen wir sie mal:) VAR_USER=festgelegter_user_in_datei_angegeben eine neue Zeile anlegen mit VAR_USER=$VAR_ABGEFRAGTER_USER.
    Dann wieder x Zeilen kopieren, unten an die erstellte Datei anhängen und die Zeile mit der nächsten Variable wieder (nennen wir sie mal VAR_APPLICATION_DATA=/home/applicationxyz) durch den Text VAR_APPLICATION_DATA= und der Variable, die in dem Programm oberhalb durch Benutzereingabe (read) abgefragt worden ist $APPLICATION_DATA ersetzen (bzw. statt der nicht mit kopierten Zeile diese einfügen).
    Und diesen Schritt für alle Variablen (5 stk.) wiederholen.

    Ich habe nur leider überhaupt keine Ahnung wie ich das jetzt bewerkstelligen soll... mit sed?

    Bitte um Hilfe!

    MfG
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. smg

    smg Regex Fetischist

    Dabei seit:
    20.05.2007
    Beiträge:
    195
    Zustimmungen:
    0
    Ort:
    /home/stephan/
    Jo mit sed geht's mit awk auch, mit bash builtins sollte es auch möglich sein.
     
  4. #3 AnonStar, 10.08.2007
    Zuletzt bearbeitet: 10.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Das ist schön, dass es mit sed funktioniert.. Aber trotz vieler Tutorials und der man page verstehe ich sed immernoch nicht vollkommen.
    Außerdem habe ich kein Tutorial gefunden, dass ein Beispiel hat, indem Zeilen aus einer Datei kopiert werden UND in eine neu erstellte eingefügt werden, geschweige denn Zeilen in neu kopiert werden und zwischendurch noch anderer Text und Variablen hinzugefügt wird und dann weiterhin an die Datei drangehängt wird und diese nicht übrschrieben wird.
    Außerdem soll die Datei bei erneutem Ausführen des scripts überschrieben werden (können), wenn man andere Variablen bei den Abfragen eingeben möchte.

    Könnte mir jemand bitte ein Beispiel geben und das - wenns geht - so gut wie möglich mit den einzelnen befehlen und parametern erklären? wäre wirklich nett!

    Edit: Am besten ein Beispiel mit der einfachsten Lösung, muss also nicht unbedingt sed sein.. Will uach schnell durchblicken können x)

    MfG,

    The AnonStar
     
  5. #4 AnonStar, 12.08.2007
    Zuletzt bearbeitet: 12.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Soo.. habe das jetzt einfach mal mit echo gelöst (mit echo in datei schreiben).
    Habe aber ncoh ein paar probleme.
    Ich habe eine Funktion menu. Dort wird via select case abgefragt welcher menüpunkt.
    Bei einem Menüpunkt habe ich am Ende folgende Abfrage:

    Code:
    echo "Einstellungen ueberarbeiten? (j / N)"
                            read RSET
                                    if [ "$RSET" == "j" ]
                                    then
                                             menu
                                    fi
    
    Leider bricht er bei eingabe von "j" nicht ab und leitet zurück zum Menü sondern macht einfach weiter.
    Im Anfangsstadium der Datei gings schonmal halb, aber da war folgender Fehler:
    Er leitete zum Menü (Menü wird angezeigt) aber das Programm wurde beendet.

    Welchen Fehler hab' ich da gemacht? - Wie gesagt, ich bin Anfänger im Shell programmieren.

    ----

    So, 2.:

    In mehreren Menüpunkten müssen die gleichen Funktionen mit eingegebenen Variablen ausgeführt werden.
    Da ich nicht bei jedem Menüpunkt den gleichen Quelltext einfügen möchte, würde ich gerne zu einer Sprungmarke springen, den Code dort ausführen und wieder zu der Stelle zurückspringen.´Beim Rücksprung müsste die Sprungmarke via Variable erfolgen, damit er zum richtigen Menüpunkt zurück springt. Einfacher wärs, wenn das parallel erledigt werden könnte...

    Wie kann ich soetwas verwirklichen?

    ----

    Zum 3. Punkt:

    Ich schreibe in eine Datei durch das Script Ports und User, die ich vergebe.
    Da Ports nur einmal vergeben werden können, sollte das Script bei einer Port-Eingabe überprüfen, ob der Port bereits verwendet wird.
    Die Datei sieht in etwa so aus:

    Code:
    25015 gs01
    24015 gs01
    23015 gs01
    
    Vielen Dank schonmal an alle, die mir helfen =)
     
  6. #5 floyd62, 12.08.2007
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Ad 1.:

    Stringvergleich in der Shell mit einfachem "=", nicht mit "==", also
    Code:
    if [ "$RSET" == "j" ]
    ändern zu
    Code:
    if [ "$RSET" = "j" ]
    und schauen, ob's hilft ...

    Ad 2.:

    GOTO ist ziemlich aus der Mode; dafür gibt's Funktionen, auch in der Shell. Der Rücksprung erfolgt dann automatisch wieder direkt an die Aufrufstelle :)

    Ad 3.:

    Na, wenn die Liste in eine Datei $FILE eingetragen wird, kannst Du ja mit "grep" prüfen, ob der zuletzt eingegebene $PORT schon vergeben ist ...
    Code:
    grep "^$PORT " "$FILE" >/dev/null && { echo "Port $PORT schon vergeben"; }
    HTH, floyd62
     
  7. #6 AnonStar, 12.08.2007
    Zuletzt bearbeitet: 13.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Hi,

    danke für die Antwort!

    Zu 1: Klappt immernoch nicht! Er zeigt zwar das Menü an, fordert aber keine Eingabe auf, sondern arbeitet die datei weiterhin ab und führt alle weiteren Befehle unterhalb der Abfrage aus (obwohl er ja zu der menu funktion gesprungen sein muss, da das menu noch mal ausgegeben wird!). Da eventuell mit Marken arbeiten? (siehe 2)

    Zu 2: Welche Möglichkeiten gibts denn da? GOTO akzeptiert und kennt meine shell nicht... Der Rücksprung scheint also (siehe 1) bei dem normalen Funktions-Aufruf automatisch zurück zu springen. Das ist gut! Nur im Fall 1 nicht xD.. Wie kann ich das da unterbinden?

    Zu 3:

    hat gut geklappt mit grep! Danke.. Nun aber ein neues Problem:

    Die Portlisten - Datei ist so aufgebaut: (anders als oben..)

    Code:
    PORT APPLICATION USER
    25015 firewall gs01
    24015 antivirus gs01
    23015 andere_app gs02
    .
    .
    .
    
    Da ich das Script mehrmals laufen lasse für einen User und eine Anwendung um evtl den Port zu ändern, muss folgendes passieren:

    Ich habe gelernt durch grep zu überprüfen, ob $USER schon mit $APPLICATION eingetragen ist.
    Code:
    $EINGETAGEN=`grep -c "$APPLICATION $USER" $FILE`
    #grep -c bestimmt die Anzahl und schreibt sie in die Variable $EINGETRAGEN
    if ["$EINGETRAGEN" != "0" ] 
    # Prüft, ob die Anzahl nicht 0 ist und soll dann die Löschung dieser Zeile(n) ausführen.
    then
       DIESE ZEILE AUS $FILE LÖSCHEN
    fi
    Ich will also, falls der User bereits mit dieser Anwendung eingetragen ist und nur der Prot gewechselt wird, die Zeile löschen, damit der User nicht doppelt mit der Anwendung und 2 verschiedenen Ports in $FILE steht.
    Aber wie lösche ich jetzt die Zeile aus $FILE, die grep mir da rausgefischt hat?

    Danke schonmal!
     
  8. #7 NoXqs, 13.08.2007
    Zuletzt bearbeitet: 13.08.2007
    NoXqs

    NoXqs Routinier

    Dabei seit:
    07.05.2007
    Beiträge:
    420
    Zustimmungen:
    0
    Ort:
    Bremen
    Code:
    EINGETAGEN=$(grep -c "$APPLICATION $USER" $FILE)
    if ["$EINGETRAGEN" > "0" ]
    then
       grep -v "$APPLICATION $USER" $FILE > $FILE 
    fi
    
    oder (finde ich persönlich schöner), Du grep'st auf den Fehlercode des letzten Befehls:

    Code:
     
    
    grep "$APPLICATION $USER"  $FILE > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
    grep -v "$APPLICATION $USER" $FILE > $FILE
    fi
    
     
  9. #8 AnonStar, 13.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Hi,

    danke, habs ausprobiert. Aber jetzt löscht er das gesamte $FILE, das heißt auch alle anderen Einträge.. das soll natürlich NICHT so sein! Wie kann ich das einstellen?

    BTW was für Arten von Sprungmarken gibts denn nun noch?
    MfG
     
  10. #9 NoXqs, 13.08.2007
    Zuletzt bearbeitet: 13.08.2007
    NoXqs

    NoXqs Routinier

    Dabei seit:
    07.05.2007
    Beiträge:
    420
    Zustimmungen:
    0
    Ort:
    Bremen
    Upps, sorry!

    Code:
    
    grep -v "$APPLICATION $USER" $FILE >> $FILE
    
    

    Und zu den Sprungmarken, denke ich, du meinst Funktionen.
    Davon ausgehend, dass du die bash benutzt, die Syntax von hier
    [function ] name () { command-list; }
     
  11. #10 SkydiverBS, 13.08.2007
    Zuletzt bearbeitet: 13.08.2007
    SkydiverBS

    SkydiverBS Tripel-As

    Dabei seit:
    15.01.2005
    Beiträge:
    207
    Zustimmungen:
    0
    Ort:
    Freising
    Das hilft ihm aber auch nicht weiter, da die zu löschenden Zeilen nicht gelöscht werden, sondern die nicht zu löschenden Zeilen nochmal ans Ende der Datei angehängt werden.

    Der ursprüngliche Befehl
    Code:
    grep -v "$APPLICATION $USER" $FILE > $FILE
    war schon korrekt. Allerdings führt die Umleitung in $FILE dazu, dass diese Datei zunächst geleert wird. Dann erst wird grep ausgeführt, was zu einer leeren Datei führt. Wir müssen das Ergebnis des grep-Aufrufs in eine zweite Datei zwischenspeichern und die originale Datei durch diese ersetzen. z.B. so:
    Code:
    grep -v "$APPLICATION $USER" $FILE > $FILE.new
    mv $FILE.new $FILE
    Das kannst du nicht. Du solltest die Menu-Funktion so aufbauen, daß automatisch dahin zurückgesprungen wird, wenn ein bestimmer Programm-Tel abgefertigt ist. Poste doch mal deine menu-Funktion, dann können wir dir besser weiterhelfen.

    Gruß,
    Philip
     
  12. NoXqs

    NoXqs Routinier

    Dabei seit:
    07.05.2007
    Beiträge:
    420
    Zustimmungen:
    0
    Ort:
    Bremen
    Du hast völlig recht. Es kann nur über die zweite Datei und den mv gehen.
     
  13. #12 AnonStar, 13.08.2007
    Zuletzt bearbeitet: 13.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Hi,

    Danke an NoXqs, funktioniert jetzt alles!
    Danke auch an SkydiverBS, bin auf die Lösungen schon selbst gekommen ;)
    Hab das mit grep genauso wie Du.

    Habe auch folgendes gelöst:

    Code:
    echo "Einstellungen ueberarbeiten? (j / N)"
                            read RSET
                                    if [ "$RSET" == "j" ]
                                    then
                                             CHANGE=1
                                             routine
                                    fi
    
    [... jetzt bei der Funktion] 
    routine () {
    .
    .
    .
    if [ "$CHANGE" == "1" ]
    then
       echo "Beende..."
       exit 0
    }
    routine
    fi
    Habe das mit menu ganz rausgenommen, da die menu - Funktion beendet ist, bevor die while case schleifenabfrage überhaupt gestartet wird. Außerdem benötige ich die Änderungen erst in Routine.

    Hätte ich die if-Abfrage nicht gemacht, dann würde er zum Anfang der routine zurückspringen, alle Daten werden neu eingegeben und alles wird ausgeführt.
    Danach würde aber alles nach der Änderungsabfrage erneut ausgeführt. Das unterbinde ich damit.

    Habe aber ein neues Problem:

    Ich habe 2 Scripts für eine Anwendung. Ein Script ist dafür, dass die $APPLICATION beim Booten startet. Das andere dafür, dass man die $APPLICATION starten, beenden und restarten kann.
    Folgendes Problem besteht jetzt aber: Wenn das boot script die $APPLICATION startet, kann ich mit dem normalen Script diese nicht mehr beenden.

    Dazu 2 Auszüge.

    Aus dem boot Script:

    Code:
    start)
        if [[ `su $USER -c "screen -ls |grep $NAME"` ]]
           then
           echo "$APP is already running!"
        else
           echo "Starting $DESC: $NAME"
           su $USER -c "cd $DIR; screen -m -d -S app ./$DAEMON $PARAMS"
        fi
        ;;
    und aus dem normalen Script:

    Code:
    status () { # Diese Funktion muss hier "true" sein
       case "$usagetype" in
       root)
        su - $USER -c "screen -ls" | grep [.]$NAME[[:space:]] > /dev/null
       ;;
       nonroot)
        screen -ls | grep [.]$NAME[[:space:]] > /dev/null
       ;;
       esac
    }
    Aufgefallen sind mir die beiden Zeilen:

    BootScript:

    Code:
    if [[ `su $USER -c "screen -ls |grep $NAME"` ]]
    
    ist anders als die Überprüfung aus dem normalen Script

    Code:
    su - $USER -c "screen -ls" | grep [.]$NAME[[:space:]] > /dev/null
    
    Ich denke, dass da ein Fehler drin steckt. Aber wie muss das dann anders sein?

    MfG,

    The AnonStar

    P.S.: Nochmal Danke an alle ;)
     
  14. #13 AnonStar, 15.08.2007
    AnonStar

    AnonStar Jungspund

    Dabei seit:
    10.08.2007
    Beiträge:
    14
    Zustimmungen:
    0
    Kann mir hier keiner mehr helfen?
     
  15. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  16. NoXqs

    NoXqs Routinier

    Dabei seit:
    07.05.2007
    Beiträge:
    420
    Zustimmungen:
    0
    Ort:
    Bremen
    Im Bootscript ist es eine Abfrage, ob die $APLLICATION läuft.

    Im Startscript ist es nur eine Befehlszeile, keine Überprüfung.
    Die Überprüfung in der CASE-Section ist auf $usagetype.
    Wenn root dieses script ausführt, wird der Befehl als User $USER ausgeführt, wenn es ein nicht-root user ist, führt dieser die Zeile aus.
    Das Ergebnis dieser beiden Befehle wird aber, soweit ich das sehe nicht weiter verarbeitet.
    Sie werden ausgeführt und gut ist. Das scheint mir nicht richtig zu sein.
    Muss die Ausgabe vielleicht in eine Variable geschrieben werden, um später den status abfragen zu können??
     
  17. #15 Fallout, 15.08.2007
    Zuletzt bearbeitet: 15.08.2007
    Fallout

    Fallout Doppel-As

    Dabei seit:
    02.03.2007
    Beiträge:
    120
    Zustimmungen:
    0
    Hi,

    was genau funktioniert denn dabei nicht? Du sagst, das bootscript funktioniert - die "application" wird gestartet und läuft.
    Der Ausschnitt aus dem normalen Script scheint eine Status-Funktion aus einem start-/stop-Script zu sein, welches den bool'schen Zustand zurückgibt (0 / 1 ...).

    Deine Status-Funktion sollte daher diesen Rückgabewert ($?) noch in eine entsprechende Meldung umsetzen, z. B.:

    Code:
    status () { # Diese Funktion muss hier "true" sein
       case "$usagetype" in
       root)
        su - $USER -c "screen -ls" | grep [.]$NAME[[:space:]] > /dev/null
       ;;
       nonroot)
        screen -ls | grep [.]$NAME[[:space:]] > /dev/null
       ;;
       esac
      [b][ $? -eq 0 ] && echo "$NAME running" || echo "$NAME not running"[/b]
    }
    Aber da ein remark schon besagt, daß die Funktion true zurückgeben sollte, wird diese Rückgabe vermutlich nach dem Aufruf der Funktion an anderer Position des Scriptes weiterverarbeitet.

    Eine andere Möglichkeit wäre, die Rückgabe des jeweiligen Befehls mit Hilfe von bool'schen Verknüpfungen direkt auszuwerten:
    Code:
    su - $USER -c "screen -ls" | grep [.]$NAME[[:space:]] > /dev/null && echo "$NAME running" || echo "$NAME not runnging"
    Gruß Daniel
     
Thema:

Neue ausführbare Datei mit Datensätzen aus einer Datei und Variablen erstellen

Die Seite wird geladen...

Neue ausführbare Datei mit Datensätzen aus einer Datei und Variablen erstellen - Ähnliche Themen

  1. Dateiinhalte vergleichen - Neue Sätze dann ausgeben

    Dateiinhalte vergleichen - Neue Sätze dann ausgeben: Liebe Forumsmitglieder, ich benöte mal wieder Eure Hilfe: Ich möchte 2 Dateien vergleichen. Datei-1 hat z.B. 100 Datensätze mit mehreren Feldern...
  2. Plasma Mobile erhält neue Basis

    Plasma Mobile erhält neue Basis: Die Entwickler der mobilen Version von KDE Plasma haben für die Plattform einen neuen Unterbau entwickelt. Das ursprünglich verwendete Ubuntu...
  3. Neues Mitglied - Hallo erstmal

    Neues Mitglied - Hallo erstmal: Hallo alle zusammen im Forum, ich habe mich gerade neu hier angemeldet und möchte mich gerne an dieser Stelle vorstellen. Ich bin der Josef und...
  4. Raspberry Pi: Neues Kamera-Modul verfügbar

    Raspberry Pi: Neues Kamera-Modul verfügbar: Fast drei Jahre nach der ersten Vorstellung eines Kameramoduls für den Kleinstrechner Raspberry Pi liefert die hinter dem Gerät stehende...
  5. Mozilla will Thunderbird eine neue Heimat schaffen

    Mozilla will Thunderbird eine neue Heimat schaffen: Eine Projektausschreibung und ein Report auf den Webseiten von Mozilla leiten die endgültige Trennung von Thunderbird und Firefox ein. Weiterlesen...