Commando in Script ausführen

N

Nano

Foren As
Hallo zusammen, ich hab eine recht schwere Übungsaufgabe und weiss nicht genau wie ich diese bewältigen soll, eventuell kann mir jemand einen tip geben.

es geht darum ein script zu schrieben welches per readline als eine art kommandozeile fungiert, soweit so gut beim starten dieses skripts wird ein befehl für ein kommandozeileorientiertes programm mitgeben ( mit eventuellen optionen ), also in der ./myscript sh -abc . Die Aufgabe von myscript wäre es nun mit dem aufgerufenen programm ( in diesem fall sh ) zu kommunizieren.
Alle weiteren details lasse ich weg da mein Problem darin liegt wie ich obiges realisieren soll.

Meine Idee wäre im Skript einen Kindprozess mit sh auszuführen, ist das der richtige Ansatz ? kann man an den Kindprozess "Befehle" senden ?
Gibt es alternativen ?
 
Du solltest mal deinen Lehrer darauf hinweisen, dass es unsinnig ist innerhalb einer Shell (die ja das Skript abarbeitet) eine weitere aufzurufen um diese mit Befehlen zu füttern. Ansonsten würde ich expect dafür verwenden um Befehle an die aufgerufene Shell weiterzureichen.
 
Du solltest mal deinen Lehrer darauf hinweisen, dass es unsinnig ist innerhalb einer Shell (die ja das Skript abarbeitet) eine weitere aufzurufen um diese mit Befehlen zu füttern. Ansonsten würde ich expect dafür verwenden um Befehle an die aufgerufene Shell weiterzureichen.

Der Sinn des ganzen ist ja 2trangig ;) es geht sicherlich eher um die implementierung der weiteren funktionen, zudem ist "readline" vorgegeben um die eingabe zu lesen.
Mein problem besteht aber eher darin wie ich das 2te Commando starte anspreche und die "events" handeln kann.
 
Hallo!

Ich bin mir nicht sicher ob es wirklich dein Problem löst, aber mit folgendem Script wird doch alles was nach stdout geschrieben wird, über die Pipe an das übergebene Programm ($@) weitergeleitet:
Code:
#!/bin/bash
while read line; do
	echo $line
done | $@

Um das zu testen, habe ich noch ein zweites Script geschrieben, das als Empfänger für das erste Script dient:
Code:
#!/bin/bash
while read line; do
	echo $line >> reader.log
done

Das erste Script habe ich caller.sh und das zweite Script reader.sh genannt und so habe ich sie dann aufgerufen:
Code:
./caller.sh ./reader.sh

Alles was man danach eingibt wird an das reader.sh-Script weitergeleitet und dieses schreibt die empfangenen Daten in die Log-Datei.

Vielleicht hilft es dir ja weiter!

Gruß,
Philip
 
Hi,

in BASH fällt mir nur der Weg über Named Pipes ein. (In der KSH könnte man das eleganter über Coroutines lösen; keine Ahnung, ob es Vergleichbares auch in der BASH gibt - lasse mich gerne aufklären!)

Nur so als Schnellschuss, ohne auf die Details einzugehen (wie die Auswahl des Kommando-Interpreters, Fehlerbehandlung, sauberes Ende etc.):

Ein Skript "executor.sh", das Zeilen liest, die als Kommandos ausführt, das Ergebnis ausgibt, und dann noch einen Marke liefert, damit man auch weiss, wenn nichts mehr kommt:

Code:
#!/bin/bash
# @(#)executor.sh


while read CMD; do
        eval "$CMD"

        echo
        echo "---NEXT---"
done

echo "EOF on input pipe" >&2

exit 0

... und ein zweites kleines Skript, das die Named Pipes initialisiert, den Executor startet, auf Eingaben vom Benutzer wartet, die an den Executor übergibt, seine Ergebnisse abfragt und ausgibt etc.

Code:
#!/bin/sh
# @(#)runner.sh


mkfifo down
mkfifo up

/bin/sh executor.sh <down >up 2>err &
SH_PID=$!


sleep 1

exec 3>down
exec 4<up


trap "rm -f up down" 0 1 2 3 15


while :; do
        kill -0 $SH_PID && echo "Executor is still active" || { echo "ERROR: executor.sh disappeared!" >&2; break; }


        echo -e "\nCMD> \c" >&2
        read CMD
        echo "$CMD" >&3

        while read LINE <&4; do
                case "$LINE" in
                "---NEXT---")
                        break
                        ;;
                *)
                        echo "$LINE"
                        ;;
                esac
        done
done


exit 0

Sollte so etwa laufen; Start mit "sh runner.sh"; Fehlermeldungen von executor.sh landen in "err" ... wie man dann jetzt noch "readline" hier unterbringt, ist mir allerdings nicht ganz klar, sorry :(

Gruss
 
Zuletzt bearbeitet:
die ansätze sind nicht schlecht danke, aber als vorgabe sollen wir readline ( nicht read line) nutzen http://directory.fsf.org/project/readline/
um eine kommandohistory ( wie in bash implementieren zu können ) allerdings weiss ich jetzt garnicht wie ich das einbinden soll, hab mir zwar die file unter
http://ftp.gnu.org/pub/gnu/readline/readline-5.0.tar.gz runtergeladen, aber wie binde ich die jetzt in mein programm ein zumal es sich um 100erte von C files handelt ?

Hat jemand eine idee ? kann man c files in scripte einbinden ? oder bin ich hier total auf dem holzweg ?
 
Hi,

also, wenn du das Ganze wirklich als Skript implementieren sollst, fällt mir nur noch "rlwrap" (http://utopia.knoware.nl/~hlub/uck/rlwrap/) ein; in der Manual-Page davon wird auch aufgezeigt, wie man damit ein "read LINE" in einem Shell-Skript ersetzen kann, so dass man die readline()-Funktionalität ausnützen kann.

Der Verdacht drängt sich aber auf, dass das eventuell doch auf ein C-Programm hinauslaufen soll: den Kommando-Interpreter zu starten, ihn über Pipes zu füttern bzw. die Ergebnisse auszulesen, und die Interaktion mit dem Benutzer über Standard-readline-Aufrufe abzuwickeln, sollte ja kein Problem darstellen: ein bisschen Spielerei mit pipe(), dup(), fork(), close(), exec() etc. am Anfang, dann readline() ... und die Sache läuft :)

Sonst wüsste ich auch keine Möglichkeit, C-Files irgendwie auf Shell-Ebene einzubinden: die müssen immer irgendwie kompiliert (oder wenigstens interpretiert) werden ...

Gruss
 
ok dnake erstmal ich werde mich nochmal erkundigen , würde mich wundern da es in der vorlesung fast ausschließlich um shellscripte ging aber der verdacht hat sich mir auch bereits ansicht der bibliothek auch aufgedrängt
 
Zurück
Oben