Bash Script - Schleifen Problem


Screeny

Well-Known Member
Joined
Oct 14, 2008
Messages
4,045
Hallo :)

Ich bin momentan ein bisschen aufgeschmissen, da ich nicht genau weiß, wie ich das realisieren soll.
Es wird ein Programm gestartet und ein anderer Befehl soll gleichzeitig aufzählen, wie viele Dateien im Verzeichnis vorhanden sind.

Das Programm downloadet Dateien und gleichzeitig brauch ich eine Ausgabe der aktuellen Zahl von vorhandenen Dateien.
Ich nutze im folgenden Beispiel den cp Befehl.
Code:
<i>
</i>cp -R /ordner1 /ordner2 >/dev/null
CP erzeugt keine Ausgabe, was ja auch gut so ist. Jetzt hätte ich gerne aber eine Ausgabe wie diese hier:
Code:
echo "Files:"; ls ordner2 | wc -l
Dies klappt natürlich auch exakt einmal. Aber ich hätte das gerne in einer Schleife, die immer aktuell anzeigt, wie viele Dateien in dem Ordner sind. Und zwar genau so lange, bis der erste Befehl (cp) abgearbeitet wurde.

Wie mache ich das?
Danke für die Hilfe :)
 
Code:
cp -v ...

Zur Erklärung ein Zitat aus den Man Files:
Code:
       -v, --verbose
              explain what is being done
 
Hallo ich glaub ich hab hier gute Tipps gesehen dafür :)

http://www.script-example.com/themen/Ablauf_Schleifen.php
Code:
Zitat:
warte auf Task
:LOOP
echo in der Schleife
@ping -n 10 localhost> nul
TaskList|Find "Taskname" >NUL || If Errorlevel 1 Goto WEITER
Goto LOOP
:WEITER
Code:
mit @ping -n 10 localhost> nul wird in der Schleife 10 Sekunden gewartet,
die Befehlszeile TaskList|Find "Taskname" >NUL || If Errorlevel 1 Goto WEITER verlässt die Schleife erst, wenn der Task: "Taskname" nicht mehr läuft


Ich verstehe das so dass hier nach dem Task geschaut wird und solange der Task läuft,läuft auch die Schleife weiter.
Musst natürlich noch anpassen an deine Bedürfnisse,da ichs einfach wo rauskopiert hab :-D

Gemacht hab ich sowas nie aber vielleicht hats ja geholfen ;)
 
Screeny said:
Aber ich hätte das gerne in einer Schleife, die immer aktuell anzeigt, wie viele Dateien in dem Ordner sind. Und zwar genau so lange, bis der erste Befehl (cp) abgearbeitet wurde.
Du kannst z.B. in einer Schlaufe herausfinden, ob ein gestarteter Command noch am Laufen ist (bspw. anhand der PID und Parent PID). Läuft er noch, gibst Du die Anzahl Dateien aus, wartest und wiederholst den Vorgang bis der Command nicht mehr läuft. Wurde er bereits beendet, gibst Du nur die Anzahl Dateien aus.

Hier ein Beispiel Script:
Code:
#!/bin/bash

# run cp command and display current number of files in target directory

# source and target directory
source=/data/pkg/source_files/*
target=/data/pkg/target_files

# command to run in background
cp_cmd='cp -rp $source $target'

# command to get all running pids & parent pids (Solaris 10)
ps_cmd='ps -e -o pid= -o ppid='

# command to count number of target files
fc_cmd='find $target -type f | wc -l'

# check wait interval in seconds
wait=1

# run cp command in background
eval $cp_cmd &

# get pid & ppid for cp command
pid=$!
ppid=$$

while true; do
  # try to get pid & ppid for cp command
  p=$($ps_cmd | grep "^ *$pid \{1,\}$ppid *$") || p="0 0"
  if [ "$p" == "0 0" ]; then
    # pid & ppid not found, cp command finished
    echo "Files in directory $target : $(eval $fc_cmd)"
    break
  else
    # cp command still running
    echo "Files in directory $target : $(eval $fc_cmd)"
    sleep $wait
  fi
done
Das Script hab ich auf einer Solaris 10 Kiste erstellt und getestet. Ich nutze diese Methode um Shutdowns von Applikationen zu überwachen und bei Bedarf Prozesse zu killen.

Der Output mit einem Test Verzeichnis sieht bei mir folgendermassen aus:
Code:
sun:/data/pkg # ./cpx
Files in directory /data/pkg/target_files :       61
Files in directory /data/pkg/target_files :      164
sun:/data/pkg #
Die einzelnen Commands habe ich in eine Variable gepackt, die können je nach UNIX Derivat unterschiedlich sein.
 
Bash ist aber ne Shell für unixoide Systeme. Hab aber aus irgendeinem Grund dann gedacht, dass T4b die Frage gestellt hat. Der nutzt ja Linux. Wird wohl Zeit fürs Bett o_O

Und wer sich Bash über cygwin oder dergleichen auf Windows holt, dürfte in den allermeisten Fällen jemand sein, der sowieso eher unix-affin ist. ; )
 
Morchel said:
Bash ist aber ne Shell für unixoide Systeme. Hab aber aus irgendeinem Grund dann gedacht, dass T4b die Frage gestellt hat. Der nutzt ja Linux. Wird wohl Zeit fürs Bett o_O

Und wer sich Bash über cygwin oder dergleichen auf Windows holt, dürfte in den allermeisten Fällen jemand sein, der sowieso eher unix-affin ist. ; )
@Matze: Ich hab nen Rootserver, u remember? Der läuft mit Debian :p

@der Rest: Danke, ich schau mal, wie weit ich komme!
 
Also die einfachste variante die mir einfällt wäre wohl sowas:
Code:
#!/bin/bash 
COUNTER=0
while [  $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1 
done


edit:

by the way

warum schickst du den output nach /dev/null wenn du ihn lesen willst?
 
In bash hat man auch die Möglichkeit, for-Schleifen zu benutzen. Das sieht dann so aus:
Code:
for ((i=0; i<10; ++i)); do
echo $i
done
 
Back
Top