Forum: PC-Programmierung [Linux] Kleines Script für Programmaufruf


von embert (Gast)


Lesenswert?

Hallo,


ich bräuchte mal schnell Hilfe.
(Keine Zeit für Internet-Recherche)

In Linux habe ich ein ausführbares Programm, das mit ein paar Parametern 
aufgerufen wird.
1
./myProgram -a foo -b bar
Das Programm soll für eine Performance-Messung i-mal aufgerufen werden. 
Dabei soll der Parameter -b immer andere Müll-daten von 16Byte Größe 
erhalten.

Also, ich bräuchte dafür ein kleines Skript.
Es wäre natürlich am schönsten, wenn die Müll-daten in einer separaten 
Datei gespeichert und ausgelesen werden; das muss aber nicht sein. Die 
Daten können auch als zig Variablen direkt im Skript stehen.

Wer kann mir ein paar Tipps geben, oder das Skript schnell hinschreiben?


DANKE

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Ja.

Beitrag #5126201 wurde vom Autor gelöscht.
von embert (Gast)


Lesenswert?

Also es geht wirklich nur um den Programmaufruf in einer Schleife.
Wie ich die Performance-Messung mache, weiß ich.

von Altenpfleger (Gast)


Lesenswert?

embert schrieb:

> In Linux habe ich ein ausführbares Programm, das mit ein paar Parametern
> aufgerufen wird../myProgram -a foo -b barDas Programm soll für eine
> Performance-Messung i-mal aufgerufen werden.
> Dabei soll der Parameter -b immer andere Müll-daten von 16Byte Größe
> erhalten.
Was heisst Mülldaten? Hast du die Daten schon generiert oder kann
das einfach Zufallsdaten sein? Sollen das immer die gleichen sein
oder wirklich egal was dort steht?

Die bytes unten sind rohe bytes keine Hexstrings.

#!/bin/bash
max=100

for i in {1..$max}
do
 myprogramm -a foo -b "$(head -c 16 /dev/urandom)"
done

von embert (Gast)


Lesenswert?

Danke, Altenpfleger.

Nein, /dev/urandom geht leider nicht.
Es sollen nämlich zwei verschiedene Programme mit den gleichen Daten 
getestet werden, damit ausgeschlossen ist, dass die Daten etwas mit der 
Laufzeit zu tun haben.
Aber die Müll-daten können und sollen initial als Random angelegt 
werden. Daher die Idee die Daten aus einer separaten Datei auszulesen.

von Altenpfleger (Gast)


Lesenswert?

Ich sehe gerade dass Varibalen in Ranges nicht gehen

also entweder so
for i in {1..100}


oder C-mässig:
max=100;
for ((i=1; i<=$max; i++))

von Altenpfleger (Gast)


Lesenswert?

Wie sieht denn das Datenformat genau aus?
Wird das erst noch festgelegt oder ist das schon fest?

Ich würde die Daten als Hexstring speichern, das lässt sich einfacher
per Script zeilenweise auslesen und kann auch mal mit nem Editor schnell 
was ändern.
Wenn die Programme per Kommandozielenschalter die Daten raw haben wollen 
oder wie auch immer kann man sie voher noch entspr. einfach 
konvertieren, mit od/hd geht das einfach oder man nimmt perl und das 
eingebaute pack, php hat das auch schon drinn.

Also sag mal was deine zwei Programme für ein Format erwarten.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Du kannst die Mülldaten in der Bash mit der Environment-Variable RANDOM
zusammenbasteln und zu Beginn des Skripts RANDOM mit einem festen Wert
initialisieren. Dann liefert RANDOM bei jedem Skriptaufruf dieselbe
Zahlenfolge.

von embert (Gast)


Lesenswert?

Hi,


wie die Datei mit den Test-daten aussieht ist wurscht.

Ich kann das Programm so aufrufen:
(-b können auch weniger als 16B uebergeben werden.)
1
$ ./myProgram -a foo -b caffe

Ich denke, das sind Hex-Daten als String, oder?

von Altenpfleger (Gast)


Lesenswert?

embert schrieb:
> Ich denke, das sind Hex-Daten als String, oder?
Ja, welches Format 'myprogramm' und das andere haben müssen möchte ich 
gerne wissen, dementspr. wird das Script und die Generierung augebaut.

von embert (Gast)


Lesenswert?

Altenpfleger schrieb:
> Ja, welches Format 'myprogramm' und das andere haben müssen möchte ich
> gerne wissen, dementspr. wird das Script und die Generierung augebaut.

Das verstehe ich gerade nicht.
Wie gesagt, es handelt sich um ein ausführbares C-Programm, das bereits 
existiert.
Was der intern macht ist doch ziemlich wurscht.
Durch den Programmaufruf sieht man doch, dass er Hex-Daten frisst, die 
er als String einliest, oder?
1
$ ./myProgram -a foo -b caffe

von Daniel A. (daniel-a)


Lesenswert?

Wenn die Daten aus einer Datei kommen, geht folgender einzeiler:
1
time while IFS= read -r line; do ./myProgram -a foo -b "$line"; done < /pfad/zu/datei/mit/zufallsdaten

Wenn man die Daten generieren will, kann man sowas machen:
1
#!/bin/bash
2
# randex
3
4
count=100
5
seed="$RANDOM$RANDOM"
6
7
number='^[0-9]+$'
8
9
if [[ "$1" =~ $number ]]; then count="$1"; shift; fi
10
if [[ "$1" =~ $number ]]; then seed="$1"; shift; fi
11
12
if [ "$#" -lt 1 ]
13
then
14
  echo "Usage: $0 [count] [seed] command [args...]"
15
  exit 1
16
fi
17
18
echo "count: $count, seed: $seed"
19
20
command="$1"; shift
21
args=( $@ )
22
23
hashes=(
24
  $(seq "$seed" "$(expr "$count" + "$seed" - 1)" | while read line
25
    do echo -n "$line" | sha512sum | grep -o '^[^ ]*'
26
  done)
27
)
28
29
run(){
30
  for hash in "${hashes[@]}"
31
  do
32
    cmd=( "$command" )
33
    for arg in "${args[@]}"
34
    do if [ "$arg" = "{}" ];
35
      then cmd+=( "$hash" )
36
    elif [[ "$arg" =~ ^\{[0-9]+}$ ]]
37
      then cmd+=( "$(printf "%.$(echo "$arg"|grep -o '[0-9]*')s" "$hash")" )
38
      else cmd+=( "$arg" )
39
    fi; done
40
    eval "${cmd[@]}"
41
    state="$?"
42
    if [ "$state" != 0  ]
43
      then echo "$state: ${cmd[*]}"
44
    fi
45
  done
46
}
47
48
time run
1
./randex ./myProgram -a foo -b {16}
2
./randex 1 ./myProgram -a foo -b {16}
3
./randex 1 2 ./myProgram -a foo -b {16}

Aber ob soetwas für Performence Messungen brauchbar ist kann ich nicht 
sagen.

von embert (Gast)


Lesenswert?

Hallo und Danke,

generieren möchte ich die Daten, wie gesagt, nur einmal und dann für 
unterschiedliche Programme mehrfach die selben verwenden.

Kannst du mir deinen Einzeiler nochmal etwas aufbröseln?

Für die Performance-Messung wollte ich clock_gettime() in den Code 
eincompilieren, und die Zeit einfach ausgeben lassen. Das soll das 
genaueste sein.

von Altenpfleger (Gast)


Lesenswert?

Viel zu kompliziert, das geht mit hexdump, xxd in nem Einzeiler, 
einrahmt mit ner while die die daten liest.

von c.m. (Gast)


Lesenswert?

das hier entspricht imho deinen anforderungen
1
for a in $(seq 1 100); do ./myProgram -a foo -b "$(echo $a | md5sum | head -c16)"; done

von Daniel A. (daniel-a)


Lesenswert?

embert schrieb:
> Kannst du mir deinen Einzeiler nochmal etwas aufbröseln?
1
time while IFS= read -r line; do ./myProgram -a foo -b "$line"; done < /pfad/zu/datei/mit/zufallsdaten

time misst die Zeit, die ein Prozess verbraucht hat, im oberen Beispiel 
ist das der while-loop. Der while-loop in bash nutzt das nachfolgende 
Kommando als Bedingung, und führt dies vor jedem Schleifendurchlauf aus. 
Wenn das Programm mit einem Status beendet wird, der nicht 0 ist, wird 
die Schleife abgebrochen. Das Kommando "read", welches ein shell-builtin 
ist, mit dem Argument "line", liest die nächste Zeile vom Standard Input 
ein, und speichert diese in der Environment Variable "line". Wenn kein 
Newline gefunden wird gibt read einen Status zurück der nicht 0 ist. Das 
Semikolon (;) markiert das Ende des Kommandos, und kann auch durch eine 
neue Zeile ersetzt werden. "do" zeigt den Anfang des Schleifenrumpfes 
an, und "done" das ende davon. Die Kommandos im Schleifenrumpfes werden 
bei jedem Schleifendurchlauf ausgeführt, hier also './myProgram -a foo 
-b "$line"'. Durch das '$' Zeichen vor "line" wird "line" als Variable 
behandelt und dessen Wert vor dem Ausführen an der stelle eingesetzt. 
Die Anfürungszeichen '"' verhindern, dass Zeichen des IFS, z.B. Abstände 
im Wert der Variable "line", gesondert behandelt werden, also nicht 
zusammengefasst werden, und das Argument nicht in mehrere unterteilt 
werden kann. Das Kleinerals zeichen "<" öffnet die nachfolgende Datei, 
hier "/pfad/zu/datei/mit/zufallsdaten" zum lesen für den Ausdruck, der 
Links davon steht, hier die while-schleife. Die While schleife bekommt 
deshalb einen eigenen Prozess, eine sogenannte subshell, und der 
Standard Input dieser Subshell, und somit aller darin ausgeführten 
gestarteten Prozesse, ist die zum lesen geöffnete Datei. Deshalb liest 
diese Schleife die Datei Zeile für Zeile aus und speichert die Zeile in 
"line", bevor der die Befehle im Schleifenrumpf abgearbeitet werden.

von Altenpfleger (Gast)


Lesenswert?

Testdaten generieren:
1
#!/bin/bash
2
anzahl_datensaetze=10
3
for ((i=0; i<=$anzahl_datensaetze; i++))
4
do
5
 echo $i
6
 datensatz=$(head -c 16 /dev/urandom|hexdump -v -e '/1 "%02X"';)
7
 echo $datensatz >> testdaten.txt
8
done

Dein Testscript:
1
#!/bin/bash
2
while read line
3
do
4
 myprogram -a foo -b "$line"
5
done < testdaten.txt

von embert (Gast)


Lesenswert?

Das sieht doch vernünftig aus.
Danke Altenpfleger.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.