Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Linux/Unix ::  Bash Variable an awk übergeben  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
DKlay
Unregistrierter




Beitrag DKlay Unregistrierter 21:46:40 19.12.2014   Titel:   Bash Variable an awk übergeben            Zitieren

Hallo, ich hoffe es kann mir hier geholfen werden.

Habe leider noch nicht viel Erfahrung beim Scripten unter Linux, und komme gerade beim überreichen einer Variable für das Zwischenspeichern der Bytes für die bereits kopierten Ordner nicht weiter, weil ich ein bestimmtes Limit nicht überschreiten will.

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash
 
# give user space time
logger "[OK] Sony Media Player inserted $1"
echo yellow > /sys/class/leds/system_led/color
echo blink  > /sys/class/leds/system_led/blink
sleep 10
 
# begin deleting and transfer
echo red > /sys/class/leds/system_led/color
echo off > /sys/class/leds/system_led/blink
 
# mount storage to /mnt/usb
mount $1 /mnt/usb/
 
# change user for securti reason
 
 
# delete all curent files from storage
rm -rf /mnt/usb/MUSIC/*
 
# extract archives files in current folder
for f in /data/shares/user/*.{zip,rar}
do
    SIZE=$(du -sm $f | awk '{ print $1 }')
    if [ $SIZE > 0 ]
    then
        logger "extracting $f ..."
        echo $f | awk -F "." '
        {
            if ($2 == "zip") {
                system( sprintf( "unzip %s -d %s", $f, $1))
            }
            else {
                system( sprintf( "unrar -o+ e %s %s/", $f, $1))
            }
        }'
        # rm $f
    fi
done
 
# transfer the folders to storage for max file size ??
SIZE=0
 
mkdir /data/shares/user/backup/
 
ls -l /data/shares/user/ | grep '^d' | awk -v s=$SIZE' {
    cmd = "du -sm /data/shares/peter/" $9;
    cmd |getline $1;
    split($1, output_arr, " ");
    s += output_arr[1];
    close(cmd);
    printf("File: %s - Size: %s\n", $9, output_arr[1]);
    if (s < 6000 && "$9" != "backup") {
        system( sprintf("logger \"copying /data/shares/peter/%s to device...\"", $9));
        system( sprintf("cp -r /data/shares/peter/%s /mnt/usb/MUSIC/%s", $9, $9));
        system( sprintf("mv /data/shares/peter/%s /data/shares/peter/backup/%s", $9, $9));
    }
    print s;
}' < SIZE
 
logger "[INFO] Transfered $SIZE MB to Device"
 
 
# work done
logger "[INFO] unmounting $1..."
umount $1
 
 
logger "[INFO] Files transfer to Sony Walkman done"
echo green > /sys/class/leds/system_led/color
echo off  > /sys/class/leds/system_led/blink


Wäre dankbar über Hilfe und evtl. gibts ja bessere Möglichkeiten :live:
SeppJ
Global Moderator

Benutzerprofil
Anmeldungsdatum: 10.06.2008
Beiträge: 28070
Beitrag SeppJ Global Moderator 22:53:35 19.12.2014   Titel:              Zitieren

Kannst du genauer sagen, was dein Problem ist? Ein langes Programm und die Aussage, dass du nicht weiter kämst, ist nicht sehr hilfreich.

Was willst du erreichen? Was hast du versucht? Was erwartest du? Was passiert stattdessen?

Das Weiterverarbeiten von Ausgaben von ls ist fast immer falsch in Shellscripten. Was genau soll da erreicht werden?

_________________
Korrekte Rechtschreibung und Grammatik sind das sprachliche Äquivalent zu einer Dusche und gepflegter Kleidung.
DKlay
Unregistrierter




Beitrag DKlay Unregistrierter 00:58:48 20.12.2014   Titel:              Zitieren

SeppJ schrieb:
Kannst du genauer sagen, was dein Problem ist? Ein langes Programm und die Aussage, dass du nicht weiter kämst, ist nicht sehr hilfreich.

Was willst du erreichen? Was hast du versucht? Was erwartest du? Was passiert stattdessen?

Das Weiterverarbeiten von Ausgaben von ls ist fast immer falsch in Shellscripten. Was genau soll da erreicht werden?


Ja hast recht, hab vergessen dazu zuschreiben, dass die SIZE größe immer
den Wert 0 hat, ich weiß das ich sie zwar übergebe, aber den Wert den ich ihr dann zuweise, geht natürlich wieder verloren, weil ich den Wert den ich in awk setze nicht zurückgebe. Und das ist das Problem, somit kann ich nie prüfen ob bereits wie im Beispiel 6000 MB kopiert wurden.

Ich möchte nur wissen, ob es da eine effizientere Möglichkeit gibt, oder muss ich das die Ausgabe von awk irgendwie per echo an SIZE zurückgeben?!
SeppJ
Global Moderator

Benutzerprofil
Anmeldungsdatum: 10.06.2008
Beiträge: 28070
Beitrag SeppJ Global Moderator 01:21:16 20.12.2014   Titel:              Zitieren

Du willst also nicht von der bash etwas an awk übergeben, sondern von awk aus den Wert im Script verändern? Letztlich kann man aus einem Kindprozess keine Variablen im Elternprozess ändern. So etwas wie in Zeile 25 muss also reichen. Ich sehe aber nicht, dass bei deinem komplexeren Kommando etwas gegen diese Methode spräche.

_________________
Korrekte Rechtschreibung und Grammatik sind das sprachliche Äquivalent zu einer Dusche und gepflegter Kleidung.
DKlay
Unregistrierter




Beitrag DKlay Unregistrierter 01:34:16 20.12.2014   Titel:              Zitieren

SeppJ schrieb:
Du willst also nicht von der bash etwas an awk übergeben, sondern von awk aus den Wert im Script verändern? Letztlich kann man aus einem Kindprozess keine Variablen im Elternprozess ändern. So etwas wie in Zeile 25 muss also reichen. Ich sehe aber nicht, dass bei deinem komplexeren Kommando etwas gegen diese Methode spräche.



Genau so wie in der Zeile 25, möchte ich nun das auf Ordner anwenden und nicht
auf gepackte Datein, weil der Speicherplatz nach dem entpacken ein anderer ist.

Deswegen möchte ich alle vorhandene Ordner auf das Device kopieren, aber auf eine bestimmte Größe wie 6000 mb limitieren.

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ls -l /data/shares/user/ | grep '^d' | awk -v s=$SIZE' {
    cmd = "du -sm /data/shares/peter/" $9;
    cmd |getline $1;
    split($1, output_arr, " ");
    s += output_arr[1];
    close(cmd);
    printf("File: %s - Size: %s\n", $9, output_arr[1]);
    if (s < 6000 && "$9" != "backup") {
        system( sprintf("logger \"copying /data/shares/peter/%s to device...\"", $9));
        system( sprintf("cp -r /data/shares/peter/%s /mnt/usb/MUSIC/%s", $9, $9));
        system( sprintf("mv /data/shares/peter/%s /data/shares/peter/backup/%s", $9, $9));
    }
    print s;
}' < SIZE



Hintergrund vom ganzen Script ist, das ich per udev rule ein USB Datenträger erkennen will, und wenn das zutrifft soll er das Script abarbeiten.
SeppJ
Global Moderator

Benutzerprofil
Anmeldungsdatum: 10.06.2008
Beiträge: 28070
Beitrag SeppJ Global Moderator 02:01:49 20.12.2014   Titel:              Zitieren

Und wieso machst du es dann nicht so wie in Zeile 25?

PS: rsync kennst du? Es wirkt ein bisschen so, als würdest du es gerade nachprogrammieren...

_________________
Korrekte Rechtschreibung und Grammatik sind das sprachliche Äquivalent zu einer Dusche und gepflegter Kleidung.
DKlay
Unregistrierter




Beitrag DKlay Unregistrierter 12:12:11 20.12.2014   Titel:              Zitieren

Super vielen Dank für den Hinweis,

hätte nicht gedacht das man auch durch Ordner iterieren kann. Aber es geht ! :D

hier die Lösung:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
 
SIZE=0
 
for dir in /data/shares/user/*/
do
        CURRENT_DIR="$(basename "${dir}")"
        DIR_SIZE=$(du -sm $dir | awk '{ print $1 }')
        if [ "$((SIZE+DIR_SIZE))" -lt "6000" ]
        then
                SIZE=$((SIZE+DIR_SIZE))
                logger "copying ${CURRENT_DIR} ($DIR_SIZE MB) to device..."
                system( sprintf("cp -r /data/shares/user/%s /mnt/usb/MUSIC/%s", ${CURRENT_DIR}, ${CURRENT_DIR) );
                system( sprintf("mv /data/shares/user/%s /data/shares/user/backup/%s", ${CURRENT_DIR}, ${CURRENT_DIR) );
 
        fi
done
logger "[INFO] Transferd total $SIZE MB to device"
SeppJ
Global Moderator

Benutzerprofil
Anmeldungsdatum: 10.06.2008
Beiträge: 28070
Beitrag SeppJ Global Moderator 12:42:55 20.12.2014   Titel:              Zitieren

Das sieht doch schon gleich viel besser aus :live: .

Zitat:
Code:
awk '{ print $1 }'
Bei dieser Art von Benutzung auch besser bekannt als cut ;)

Hat es eigentlich einen tieferen Grund, warum du ein Kommando mit sprintf zusammen setzt und dann mit system ausführst, anstatt es, nun ja, einfach auszuführen? So a la
Code:
cp -r /data/shares/user/${CURRENT_DIR} /mnt/usb/MUSIC/${CURRENT_DIR}

oder, da cp nicht doof ist:
Code:
cp -r /data/shares/user/${CURRENT_DIR} /mnt/usb/MUSIC/

_________________
Korrekte Rechtschreibung und Grammatik sind das sprachliche Äquivalent zu einer Dusche und gepflegter Kleidung.
DKlay
Unregistrierter




Beitrag DKlay Unregistrierter 13:07:22 20.12.2014   Titel:              Zitieren

SeppJ schrieb:
Das sieht doch schon gleich viel besser aus :live: .

Zitat:
Code:
awk '{ print $1 }'
Bei dieser Art von Benutzung auch besser bekannt als cut ;)

Hat es eigentlich einen tieferen Grund, warum du ein Kommando mit sprintf zusammen setzt und dann mit system ausführst, anstatt es, nun ja, einfach auszuführen? So a la
Code:
cp -r /data/shares/user/${CURRENT_DIR} /mnt/usb/MUSIC/${CURRENT_DIR}

oder, da cp nicht doof ist:
Code:
cp -r /data/shares/user/${CURRENT_DIR} /mnt/usb/MUSIC/


cat würde mir doch die Größe und den Namen zurückgeben, mit print $1 gebe ich nur die Größe zurück, den Namen brauche ich ja nicht.

Und nein hat keinen tieferen Grund :D , copy & paste aus der vorherigen awk Programmierung, kann man hier natürlich weglassen.

Nochmals Danke
nman
Alt-Moderator

Benutzerprofil
Anmeldungsdatum: 19.02.2002
Beiträge: 14967
Beitrag nman Alt-Moderator 13:54:56 20.12.2014   Titel:              Zitieren

DKlay schrieb:
cat würde mir doch die Größe und den Namen zurückgeben, mit print $1 gebe ich nur die Größe zurück, den Namen brauche ich ja nicht.

cut, nicht cat. :)
Code:
du -sm $dir | cut -f 1

_________________
…but tuesday's just as bad.
C++ Forum :: Linux/Unix ::  Bash Variable an awk übergeben  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.