Fórum Ubuntu CZ/SK

Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: Matesax 15 Dubna 2013, 08:00:12

Název: [Vyřešeno] Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 08:00:12
Dobrý den,
můžu nějak použít array jako list? Podle všech možných totoriálů, wiki atd. by to mé fungovat mělo - ale nefunguje... :)

Kód: [Vybrat]
while read -r line
do
...
devices[$(($number - 1))] = "${line%:*}"
...
done < /tmp/devices.txt

Number incriminuje v každém kole. Číslo vydává správně - jelikož mi jej vypisuje error:

Kód: [Vybrat]
./install: 19: ./install: devices[@]: not found

Kde @ jsou jednotlivé hodnoty.
Jak to tedy správně udělat?
Děkuji.
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 09:41:07
Řekl bych, že především nepoužívat mezery kolem rovnítka, shell pak místo přiřazení do proměnné výraz zkouší spustit jako program a další znaky za mezerou bere jako argumenty.
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 11:22:41
To vím - toto je projev zoufalství... Když tam mezery nebyly, bral to jako string či co - v erroru byly závorky [] přilepeny k oné proměnné - poli. Zkoušel jsem 62589 kombinací - co na googlu najdete na prvních 6 stranách, to jsem již zkusil... :)
Název: Re:Bash - List
Přispěvatel: ntz_reloaded 15 Dubna 2013, 11:30:03
http://www.thegeekstuff.com/2010/06/bash-array-tutorial/

**ultimate tutorial by nestacil ?
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 11:59:57
Nevím, co jsi zkoušel, ale například tohle funguje:

Kód: [Vybrat]
#!/bin/bash
n=1
while read -r line
do
        devices[$(($n-1))]="${line%:*}"
        echo ${devices[$(($n-1))]}
        n=$(($n+1))
done < /tmp/devices.txt
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 13:42:14
http://www.thegeekstuff.com/2010/06/bash-array-tutorial/

Jsem zkoušel - slibně ale vypadá to od GdH...
Děkuji.
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 17:04:48
Kód: [Vybrat]
./install: 19: ./install: devices[0]: not found
1) /dev/sda1: UUID="f292a494-9f9f-471d-9e7e-d012596f17bd" TYPE="ext4"
./install: 19: ./install: devices[1]: not found
2) /dev/sda5: UUID="4cf54643-cd1e-4547-9ea2-6058613c7fcf" TYPE="ext4"
./install: 19: ./install: devices[2]: not found
3) /dev/sda6: UUID="0f9c79f2-0cb1-40a2-91d4-80d7adfe9bfd" TYPE="swap"
./install: 19: ./install: devices[3]: not found
4) /dev/sr0: LABEL="VOLUME IDENTIFIER" TYPE="udf"
./install: 19: ./install: devices[4]: not found
5) /dev/sdb: SEC_TYPE="msdos" LABEL="SMA-OP" TYPE="vfat"

To je pro:

Kód: [Vybrat]
devices[$(($number-1))] = "${line%:*}"

Mezera dle mého nehraje roli - jelikož inkriminace number mi funguje...

Kód: [Vybrat]
./install: 19: ./install: devices[0]=/dev/sda1: not found
1) /dev/sda1: UUID="f292a494-9f9f-471d-9e7e-d012596f17bd" TYPE="ext4"
./install: 19: ./install: devices[1]=/dev/sda5: not found
2) /dev/sda5: UUID="4cf54643-cd1e-4547-9ea2-6058613c7fcf" TYPE="ext4"
./install: 19: ./install: devices[2]=/dev/sda6: not found
3) /dev/sda6: UUID="0f9c79f2-0cb1-40a2-91d4-80d7adfe9bfd" TYPE="swap"
./install: 19: ./install: devices[3]=/dev/sr0: not found
4) /dev/sr0: LABEL="VOLUME IDENTIFIER" TYPE="udf"
./install: 19: ./install: devices[4]=/dev/sdb: not found
5) /dev/sdb: SEC_TYPE="msdos" LABEL="SMA-OP" TYPE="vfat"

To je pro:

Kód: [Vybrat]
devices[$(($number-1))]="${line%:*}"

A ještě dotaz - není v proc soubor se stejným obsahem jako je výpis blkid? Aktuálně totiž výstup blkid musím stejně ukládat do tmp - jelikož jej potřebuji číst řádek po řádku - a hádat se s cyklem aby bral string jako zdroj a ne jako cestu k souboru se mi nechce...

Abych to vysvětlil - potřebuji vypsat všechna zařízení tak, aby bylo uživateli jasné o jaké zařízení se jedná. A sice zařízení na které se dá instalovat OS - toto je totiž instalátor mého OS - SMA-OP. No a po vypsání všech zařízení na která by šlo instalovat OS si jedno z nich uživatel vybere číslem - abych z toho výpisu dostal jen cesty k zařízením potřebuji právě to pole - do kterého jen dosadím vstup uživatele jako index - pochopitelně s testem, zda se jedná o číslo...
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 20:16:09
Mezery samozřejmě roli hrají, to že to przníš někde jinde je jiná věc. Dej sem kousek konkrétního samostatně spustitelného kódu (podobně jako jsem to udělal já), který ti nefunguje a já ti řeknu proč. Ten jeden řádek, který tu ukazuješ nic neřekne. Spouštíš to opravdu v Bashi? sh != bash v Ubuntu, ani v Debianu, na to se taky mnoho lidí nachytá. Co má znamenat "inkriminace"?
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 21:03:59
Pouštím to v emulátoru - pro uživatelské pohodlí potřebuji aby to v něm jelo... Inkriminace je navýšení o 1, opakem je dekrementace - snížení o 1 - základní programátorský pojem... ++/--

http://slovnik-cizich-slov.abz.cz/web.php/slovo/dekrementace

Nefunguje mi ten konkrétní řádek - co víc bych měl poslat? Jestli si to chceš zkusit, je to v cyklu while...

Kód: [Vybrat]
#!/bin/sh

number=0

blkid > /tmp/devices.txt

while read -r line
do
number=$(($number + 1))
devices[$(($number-1))]="${line%:*}"

echo "${number}) ${line}"
done < /tmp/devices.txt
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 21:11:22
Zaprvé si inkriminaci pleteš s inkrementací a za druhé ukaž výpis
ls -l /bin/sh
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 21:22:19
Pro jistotu jsem použil:

Kód: [Vybrat]
dpkg-reconfigure bash

Výsledek stejný... Když jsem dal dash, tak to hodilo hlášku - bash ale nastaven již byl...
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 21:26:17
Proč používáš dash, když chceš použít bash? Kurnik zamysli se trochu ;)
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 21:43:13
Čti co píši - dal jsem ho jen na test... Bash mám jako defaultní a stejně to neřeší problém s arrayem - zápis je stejný... Alespoň co jsem naposledy používal dash.

Tedy:

Kód: [Vybrat]
ddd[index]=hodnota

Jenže to nejde... :)
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 21:46:37
Ten skript, co jsi dal spusť takto:

bash /cesta/ke/skriptu

Bash s tim problém nemá.
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 21:49:52
Kód: [Vybrat]
root@sam-eME642:/mnt/Data/SMA-OP# bash ./install
>>> Check for devices
./install: řádek 19: devices[0]: příkaz nenalezen
1) /dev/sda1: UUID="f292a494-9f9f-471d-9e7e-d012596f17bd" TYPE="ext4"
./install: řádek 19: devices[1]: příkaz nenalezen
2) /dev/sda5: UUID="4cf54643-cd1e-4547-9ea2-6058613c7fcf" TYPE="ext4"
./install: řádek 19: devices[2]: příkaz nenalezen
3) /dev/sda6: UUID="0f9c79f2-0cb1-40a2-91d4-80d7adfe9bfd" TYPE="swap"
./install: řádek 19: devices[3]: příkaz nenalezen
4) /dev/sr0: LABEL="VOLUME IDENTIFIER" TYPE="udf"
./install: řádek 19: devices[4]: příkaz nenalezen
5) /dev/sdb: SEC_TYPE="msdos" LABEL="SMA-OP" TYPE="vfat"

Tak jsem blbý já? :) Bože - proč jsou shelly tak blbě navrženy? Tedy proč to nemůže být normální C? Nechápu význam těch machinací...

EDIT:

Kód: [Vybrat]
#!/bin/bash

Konečně! :)

Ještě k tomu výpisu dostupných DriveDevices - je na to tedy nějaký pěkný soubor v proc?
Děkuji.
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 21:59:03
Za prvé - na první řádek skriptu se píše interpret - když chci použít bash, napíšu tam např. #!/bin/bash
Za druhé - první řádek s interpretem je ignorován, když skript spustíš rovnou v interpretu, jak jsem ti teď napsal
Za třetí - /bin/sh vždy ukazuje na systémový shell, ve kterém jsou všechny init skripty a měnit to bude jen sebevrah. V debianích systémech je to dash.
Za čtvrtý - pokud si v systému uděláš bordel, je to tvoje věc ;)
Název: Re:Bash - List
Přispěvatel: ntz_reloaded 15 Dubna 2013, 22:30:17
v bashi (a ne v bin/sh) me to vypisuje asi tohle - coz je spravne, ze:

Kód: [Vybrat]
# ./foo.sh
1) /dev/sda1: UUID="391ae98d-666f-4202-adea-8066cd425ece" TYPE="ext3"
2) /dev/sda2: UUID="3686b597-3941-47d1-9af1-5a9485812c3a" TYPE="swap"
3) /dev/sda5: UUID="ae5f539d-d7d2-4ac2-8fa7-1d9f4bb4dfd0" TYPE="ext4"
4) /dev/sda6: UUID="660875c3-59f1-4f5a-b5ed-9f091a025d7a" TYPE="ext4"

nicmene kdybych chtel tenhle vypis, tak udelam:

Kód: [Vybrat]
# blkid | cat -n - | perl -pe 's/^\s+(\d+)\s+/$1\) /'
1) /dev/sda1: UUID="391ae98d-666f-4202-adea-8066cd425ece" TYPE="ext3"
2) /dev/sda2: UUID="3686b597-3941-47d1-9af1-5a9485812c3a" TYPE="swap"
3) /dev/sda5: UUID="ae5f539d-d7d2-4ac2-8fa7-1d9f4bb4dfd0" TYPE="ext4"
4) /dev/sda6: UUID="660875c3-59f1-4f5a-b5ed-9f091a025d7a" TYPE="ext4"

pozor .. perl -pe !!je emulace sedu, akorat se tam pise normalni RE a nemusis to vsechno escapovat jako v sedu .. neni to zadna magie, ja sed skoro nepouzivam, ale bylo by to stejny
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 22:35:07
Mě je samotný výpis k ničemu... Potřebuji hlavně cestu k zařízení - ostatek je pro uživatele... Pole mi stále nefunguje - sice to již nehlásí error, ale zařízení se nevybere...

Kód: [Vybrat]
while read -r line
do
number=$(($number + 1))
devices[$(($number-1))]="${line%:*}"

echo "${number}) ${line}"
done < /tmp/devices.txt

echo ">>> Select target device please (1-${number}):"

while true
do
read opt

if [[ $opt > 0 && $opt -le $number ]]
then
break
else
echo ">>> Bad input - try again..."
fi
done

device=$devices[$opt]

Navíc bych chtěl ten výpis co nejlidštější - aby i lajk mohl snadno poznat o jaké zařízení se jedná - pak jen zadá číslo a instalace proběhne sama... Ještě dodělám zápis do DVD a bude to komplet... :)

Aktuální stav:

Kód: [Vybrat]
root@sam-eME642:/mnt/Data/SMA-OP# ./install
>>> Checking for devices
1) /dev/sda1: UUID="f292a494-9f9f-471d-9e7e-d012596f17bd" TYPE="ext4"
2) /dev/sda5: UUID="4cf54643-cd1e-4547-9ea2-6058613c7fcf" TYPE="ext4"
3) /dev/sda6: UUID="0f9c79f2-0cb1-40a2-91d4-80d7adfe9bfd" TYPE="swap"
4) /dev/sr0: LABEL="VOLUME IDENTIFIER" TYPE="udf"
5) /dev/sdb: SEC_TYPE="msdos" LABEL="SMA-OP" TYPE="vfat"
>>> Select target device please (1-5):

Což mi pořád nepřijde dost lidské...
Název: Re:Bash - List
Přispěvatel: GdH 15 Dubna 2013, 22:40:13
device=$devices[$opt]  >>  device=${devices[$opt]}
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 22:45:10
Jede to! Děkuji.
Název: Re:Bash - List
Přispěvatel: Matesax 15 Dubna 2013, 22:57:15
Tak mám ještě jeden problémec. :) Na konci instalace ještě kopíruji externí programy (které jsou již hotové, aniž bych je v průběhu instalace kompiloval) a hned po tom kopírování umountovávám cílové zařízení. Jenže to se nezdaří, jelikož kopírování ještě probíhá. Sleep použít nechci - protože to je jen tipovačka... Dalo by se zařídit vyloženě počkání na dokopírování?
Děkuji.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 07:09:54
Tak nakonec jsem si to udělal sám - ale nedaří se mi dostat velikost složky v čísle - jak na to jít?

Kód: [Vybrat]
originSUR=`du -sb "${path}/done"`
targetSUR=`du -sb "${path}/tmp"`

origin="${originSUR%${path}*}"
target="${targetSUR%${path}*}"

Jenže mezery bohužel ignorovány nejsou - jak tedy do {} dostat jako pattern mezeru? Převrácené lomítko a s nefunguje. A dalo by se to osekat bez mezikroku - rovnou z ``?
Děkuji.
Název: Re:Bash - List
Přispěvatel: jmp 16 Dubna 2013, 07:41:05
cyklus se sleepem, dokud vysledek nasledujiciho nebude nula?
Kód: [Vybrat]
lsof $umisteni | wc -ljinak
Kód: [Vybrat]
man lsof
Kód: [Vybrat]
man wc
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 15:23:02
Kód: [Vybrat]
WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/sam/gvfs
Output information may be incomplete.

Mám to:

Kód: [Vybrat]
while [ $origin -ge $copied ]
do
$copied=$((`lsof tmp | wc -l` - target))
pct=$((100 * $copied / $files))

echo -en ".$pct%\b\b\b"
sleep 1
done
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 16:40:24
Kód: [Vybrat]
path=`pwd -P`

getDirSize()
{
ret=`sudo find "${path}/${1}" -printf "%s\n" | awk '{sum+=$1} END {printf "%d\n", sum}'`
}

getDirSize done

origin=$ret

getDirSize tmp

target=$ret

copied=0

cp done/* tmp

while [ $origin > $copied ]
do
getDirSize tmp
copied=$(($ret - $target))
pct=$((100 * $copied / $origin))

echo -en ".$pct%\b\b\b"
sleep 1
done

Toto se zasekne na 0 - proč?
Děkuji.
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 20:37:56
Tak už jsi na to přišel?
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 20:51:57
Jsem schopen dostat velikost v bytech o něco snadněji, ale prostě se to zasekne...

Kód: [Vybrat]
getDirSize()
{
list=`du -sb "${path}/${1}"`
ret=`echo $list | sed -e 's/\s.*//'`
}

getDirSize "done"

origin=$ret

getDirSize "tmp"

target=$ret

copied=0

cp done/* tmp &

while [ $origin > $copied ]
do
getDirSize "tmp"
copied=$(($ret - $target))
pct=$((100 * $copied / $origin))

echo -en ".$pct%\b\b\b"
sleep 1
done

Napadá mne jen, že cyklus kopírování přeruší... Což by nastavení do pozadí podle mě mělo vyvrátit - ale neděje se nic... Respektive byty nepřibývají a tak se cyklus neukončí.
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 21:45:54
Podívej se jak se v bashi porovnávají čísla.

Kód: [Vybrat]
path=`pwd -P`
getDirSize()
{
        ret=`du -sb "${path}/${1}"|sed 's/\s.*//'`
}

getDirSize "done"
origin=$ret
getDirSize "tmp"
target=$ret

copied=0

cp done/* tmp &

while [ $origin -gt $copied ]
do
        getDirSize "tmp"
        copied=$ret
        pct=$((100 * $copied / $origin))

        echo -en "\b\b\b.$pct%"
        sleep 1
done

Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 21:48:00
Mělo by jít i to s operandem... Každopádně to s optionem dá:

Kód: [Vybrat]
./install: řádek 121: [: -qt: očekáván binární operátor
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 21:51:32
Už konečně používáš Bash? Já ano a ten kód jsem testoval. Jinak stále používáš své doměnky, místo aby sis ověřoval fakta. Operátory, na které jsi zvyklý, se v Bashi používají jen na porovnávání řeťezců.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 21:57:30
Kdybych nepoužíval Bash, nejela by ta část před tím... Už jsem posílal novou hlavičku souboru... Je hezké, že tobě to jde, ale mě ne... :)

Kód: [Vybrat]
path=`pwd -P`

getDirSize()
{
list=`du -sb "${path}/${1}"`
ret=`echo $list | sed -e 's/\s.*//'`
}

Neřídím se domněnkami, ale:

http://tldp.org/LDP/abs/html/comparison-ops.html
getDirSize "done"

origin=$ret

getDirSize "tmp"

target=$ret

copied=0

cp done/* tmp &

while [ $origin -qt $copied ]
do
getDirSize "tmp"
copied=$(($ret - $target))
pct=$((100 * $copied / $origin))

echo -en ".$pct%\b\b\b"
sleep 1
done

Neřídím se domněnkami, ale:

http://tldp.org/LDP/abs/html/comparison-ops.html
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 22:01:10
Já ale píšu o kódu, který jsem vložil já, ten tvůj jsem ani nezkoušel.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 22:02:26
Joo - mám tam sice qt místo gt, ale gt mi zase stagnuje - nic se neděje - kód se zacyklí...
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 22:06:01
Podívej se na ten cyklus pořádně.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 22:09:02
Ale to je přeci blbost - já musím anulovat dosavadní velikost cílové složky - chci dostat jen přírůstek... Jak to mám teď - zjistím si velikosti složek zdrojové a cílové. Začnu kopírovat a v cyklu se ptám na velikost cílové - velikost cílové před kopírováním...
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 22:18:20
Dělej si to jak chceš, mně to prostě ukazuje od nuly do sta procent a pak to skončí jak má.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 22:27:35
Mě se ale prostě nezmění velikost - ta před a po je stejná... To proto se to zacyklí... Může hrát roli, že cílem je USB? Tedy namountovaný sdb do složky?
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 22:37:09
Rozhodně by to nemělo být důvodem zacyklení, zásadnější rozdíl je jen v tom, že usb je pomalejší a hraje daleko větší roli cache. Nejsem si teď jist, jak přesně funguje du, ale je jisté, že cp skončí dříve, než jsou data skutečně fyzicky na disku.
Název: Re:Bash - List
Přispěvatel: Matesax 16 Dubna 2013, 22:44:52
Nechal jsem cyklus běžet 5 minut - tak to už nevysvětlíš... :) Velikost se prostě za běhu scriptu nezměnila...
Název: Re:Bash - List
Přispěvatel: GdH 16 Dubna 2013, 23:03:51
Napadlo tě zjistit si velikosti, které jsou porovnávány, jaký je konečný rozdíl? Jakou velikost má prázdný adresář?

Na mém systému:

Kód: [Vybrat]
path=`pwd -P`
getDirSize()
{
        ret=`du -sb "${path}/${1}"|sed 's/\s.*//'`
}

getDirSize "done"
origin=$ret
getDirSize "tmp"
target=$(($ret-4096))
copied=0

cp done/* tmp &

while [ $origin -gt $copied ]
do
        getDirSize "tmp"
        copied=$(($ret-$target))
        pct=$((100 * $copied / $origin))

        echo -en "\b\b\b$pct%"
        sleep 1 
done
echo
Název: Re:Bash - List
Přispěvatel: Matesax 17 Dubna 2013, 05:51:33
Tak to mi neuvěříš... :) Já už jsem před tím testoval instalaci - ony soubory už tam byly... I tak se to zasekne na 96 procentech - tuším, že bude problém v samotné složce...
Název: Re:Bash - List
Přispěvatel: Matesax 17 Dubna 2013, 07:09:57
Já to snad nedám do kupy... :)

Kód: [Vybrat]
for f in done/*
do
if [[ $tFiles == *`basename $f`* && $all == false ]]
then
echo ">>> The target device already contains files from Done directory...";
echo ">>> Overwrite it? (all/y/n)"

read overwrite

if [ "$overwrite" = "y" ]
then
rm tmp/`basename $f`
elif [ "$overwrite" = "all" ]
then
all=true
rm tmp/`basename $f`
fi
elif [[ $tFiles == *`basename $f`* ]]
then
rm tmp/`basename $f`
else
getDirSize tmp/`basename $f`

target=$(($target - $ret))
fi
done

cp done/* tmp &

while [ $origin -gt $copied ]
do
getDirSize "tmp"
copied=$(($ret - $target))
pct=$((100 * $copied / $origin))
echo $target
echo -en ".$pct%\b\b\b"
sleep 1
done

Nyní vezmu počáteční velikost cílové složky a od ní odečítám ty soubory, které uživatel nechce smazat. Ostatní se smažou - a tak je třeba jejich velikost odečíst od target, jelikož o target pak budu snižovat velikost zkopírované části... Pak když kopíruji, tak to hodí prvně 76% a někdy 96%, ale pak už zase 0 a zacyklí se to...
Název: Re:Bash - List
Přispěvatel: GdH 17 Dubna 2013, 10:56:04
Mně to tu už nebaví ;)

cp kopíruje všechny soubory a je jedno, zda tam už jsou, nebo ne.
Pokud tedy počítáš s tím, že tam jsou nějaké stejné soubory, přinejmenším jménem, musíš je předem smazat, nebo je vůbec nekopírovat a zohlednit to ve výpočtech. Kopírovat je přes a spoléhat se na to, že jsou stejné velikosti není zrovna moudré a rozhodně bys nemohl sledovat průběh kopírování porovnáváním velikosti před a po.
Ve smyčce musíš porovnávat relevantní data, což zahrnuje i odečtení velikosti samotného adresáře od dat, která jsou v něm uložena, protože ten rozdíl, který vypočítáš z aktuální velikosti cílového adresáře oproti původní, adresář logicky nezahrnuje.
Název: Re:Bash - List
Přispěvatel: Matesax 17 Dubna 2013, 16:00:37
Co píšeš jsem přesně udělal - shodné soubory se smažou pokud to uživatel povolí... Odečítám jen zbylé soubory...

Dále cp nepřepisuje soubory, jen s optionem f. A jde logicky o to, že když jsem vzal původní velikost a soubory se jen přepsaly (nebo vůbec nekopírovaly), tak se výsledná velikost nezměnila...
Název: Re:Bash - List
Přispěvatel: GdH 17 Dubna 2013, 16:16:34
Takže hotovo? :)
Název: Re:Bash - List
Přispěvatel: Matesax 17 Dubna 2013, 16:59:28
Právě, že to nefunguje... Jak jsem psal - vypíše to 76%, či 96% a pak opět 0 a zacyklí se to...
Název: Re:Bash - List
Přispěvatel: GdH 17 Dubna 2013, 17:40:30
Úloha je to dostatečně triviální, aby nebyl problém vystopovat důvod chování tvého skriptu. Co jsem sem vložil a napsal, to jsem si ověřil empiricky a všechno sedí a funguje, moje počítadla problém nemají flaška neflaška. Teď už je to na tobě.
Název: Re:Bash - List
Přispěvatel: Matesax 19 Dubna 2013, 07:28:55
Tak ta úloha zase tak triviální není... :) Už jsem našel problém - velikost souborů je sice stejná, ale užití na disku jiné. DU očividně měří velikost na disku. Jak tedy dostat velikost souborů?
Název: Re:Bash - List
Přispěvatel: GdH 19 Dubna 2013, 08:42:19
Tak triviální, abys na tento fakt přišel do pěti minut  ;)
Název: Re:Bash - List
Přispěvatel: Matesax 19 Dubna 2013, 15:24:49
Joo - du jsem nakonec použil - ale s /*, místo velikosti mateřské složky... Bůh ví, co budu dělat až tam budou subsložky... To si to rovnou napíši do bootloaderu a bude... :) Tedy abych nebyl prase, udělám to raději zvlášť... :) Každopádně děkuji.
Název: Re:[Vyřešeno] Bash - List
Přispěvatel: GdH 19 Dubna 2013, 15:44:22
du prostě počítá i s velikost adresářů, to jsem ti psal už dřív. Můžeš si hrát i s dalšími příkazy, např:

Kód: [Vybrat]
find -type f -ls | awk '{total += $7} END {print total}'
Tohle spočítá pouze regulérní soubory (rekurzivně), tedy ne symlinky, adresáře a jinou havěť ;)

Edit: jedna uvozovka mi vypadla..
Název: Re:[Vyřešeno] Bash - List
Přispěvatel: Matesax 19 Dubna 2013, 16:43:56
Děkuji - na základě tvého příspěvku jsem zdokonalil svůj kód:

Kód: [Vybrat]
du -b ./* | awk '{total += $1} END {print total}'
Název: Re:[Vyřešeno] Bash - List
Přispěvatel: GdH 19 Dubna 2013, 17:06:43
Tak hlavně nezapomeň na to, že tu hvězdičku ti nahrazuje soubory shell a pokud budeš mít v adresáři jméno s mezerou, skončí to špatně ;)

Název: Re:[Vyřešeno] Bash - List
Přispěvatel: Matesax 19 Dubna 2013, 17:08:55
Shell jsem si upravil pro Češtinu a tyto případy - escapuji...

Jen mám nyní opačný problém - mezitím co před tím vyšlo číslo moc malé a zacyklilo tak cyklus  :o , nyní naopak vydá moc velké číslo - 127%. Přitom po použití stejných příkazů někde mimo, dosahuji správných hodnot... :)

Kód: [Vybrat]
origin=0

target=0

copied=0

tFiles=`ls tmp`
all=false

for f in done/*
do
getSize $f

origin=$(($origin + $ret))

if [[ $csys == false ]]
then

if [[ $tFiles == *`basename $f`* && $all == false ]]
then
echo ">>> The target device already contains files from Done directory...";
echo ">>> Overwrite it? (all/y/n)"

read overwrite

if [ "$overwrite" = "y" ]
then
rm tmp/`basename $f`
elif [ "$overwrite" = "all" ]
then
all=true
rm tmp/`basename $f`
else
getSize tmp/`basename $f`

target=$(($target + $ret))
fi
elif [[ $tFiles == *`basename $f`* ]]
then
rm tmp/`basename $f`
fi
fi
done

cp done/* tmp &

while [ $origin -gt $copied ]
do
copied=$((`du -bc tmp/* | tail -1 | sed -e 's/\s.*//'` - $target))
pct=$((100 * $copied / $origin))

echo -en "\r>>> Progress: ${pct}%\r"
sleep 1
done

echo ">>> Unmounting the target device..."

umount tmp

A větší problém - bez sleep se nestihne dokončit kopírování - cyklus ale skončit dříve nesmí. Proč tedy skončí?
Děkuji.
Název: Re:[Vyřešeno] Bash - List
Přispěvatel: GdH 19 Dubna 2013, 17:34:07
Pokud blbě počítáš, tak asi může skončit dřív. Pokud chceš odpojovat zařízení, měl bys počkat na sync, je tu taky cache, pokud nenamountuješ v synchroním režimu, ....