Šta je novo?

Pomoc BASH prijatelja

Gaston

Čuven
Učlanjen(a)
12.07.2003
Poruke
265
Poena
620
Moja oprema  
Pristup internetu
  1. Kablovski internet
Svaki dan u odredjeno vreme mi na sftp server spustaju fajlove u formatu imedatum_vreme (primer fajla: CERT_sbrtcn240117n_0841.GPG). Napravio sam skript koji "hvata" ime, ali vreme mi *ebe kevu. Skript gleda fajl koji je stigao sa datumom prethodnog dana, otpakuje ga i iskopira u folder na drugom serveru. Kako da mu kazem da gleda i vreme? Ako napravim promenjlivu dt (dt=$(date -d "1 day ago" +'%Y%m%d_%H%M') lepo mi da datum, ali prilepi vreme pokretanja skripta i, naravno, ne nadje fajl koji mi treba. Ubih se ovako neuk da resim problem, ali mi ne ide. Moze li neko da mi otvori oci, molim vas?

Zaboravih, fajlovi stizu svaki dan, ne samo od ponedeljka do petka.
 
Poslednja izmena:
Daj malo vise detalja. U čemu pišeš skript (windows, linux, ...)? Možda nije loše da ovde okačiš tvoj postojeći skript, naravno očišćen od privatnih podataka.
 
@gadafi Linux i BASH :)

@Gaston Okači skriptu na pastebin.com recimo, možda ti ima pomoći
 
@Neky Tek sam kasnije video da je pitanje u Linux delu foruma :)
 
Izvinjavam se, mislio sam da je ocigledno da je u pitanju bash skript (server je Ubuntu 14.04.5 LTS). Ispod je primer skripta koji radi:

#!/bin/bash

log='/tmp/cpu1/log.txt'

rm -rf $log

echo 'Subject: report file' >> $log
echo '' >> $log


pass='neki_pass'

now=$(date -d "1 day ago" +'%Y%m%d')
echo $now

file_cert01='CERT_JU_SSIM_'$now'.TXT.gpg'
file_cert02='CERT_JU_SSIM_'$now'.gpg'
file_cert03='CERT_JU_SSIM_'$now'.txt'

cp -rf '/SFTP/CERT/SSIM/'$file_cert01 '/tmp/cpu1/cert/'$file_cert02 >> $log

cp -rf '/tmp/cpu1/cert/'$file_cert02 '/tmp/cpu1/cert/decrypted_cert/'$file_cert02 >> $log

gpg --batch --yes --passphrase $pass -o '/tmp/cpu1/cert/decrypted_cert/'$file_cert03 --decrypt '/tmp/cpu1/cert/decrypted_cert/'$file_cert02 >> $log

cat $log | msmtp --file=/etc/msmtprc [email protected]

Radi za fajlove koji nemaju vreme u imenu vec samo datum.

Hvala!
 
Ok, daj mi primer imena fajla koji radi, i primer imena fajla koji ne radi.
 
Sa ovim nemam problem: CERT_JU_SSIM_20170116.TXT.gpg
Ovo me ubija: CERT_tvcr200117JU_0812.GPG

_0812 je vreme kad je fajl kreiran kod partnera. Najgore je sto ce se to vreme menjati. Meni najgore. Za sad smo u test fazi, pa fajl stize jednom dnevno. Ne u isto vreme! A kad predjemo u produkciju, faljovi ce stizati vise puta dnevno. Mislim, ja se bavim mrezama, a uvalise mi ovo cudo dok se kolega sysadmin ne vrati na posao...
 
Hm...otkud sad "JU" između datuma i vremena? :)
 
Dao sam dva tipa fajlova. Ima ih svakako nazvanih, ali ime nije ono sto me muci. Vreme na kraju imena ispred underscore znaka.
 
Poslednja izmena:
Možeš li što detaljnije da mi opišeš šta tvoj skript treba da radi? Najviše me interesuje "pronalazak fajla" - koliko fajlova može da bude, na osnovu čega ih traži? Da li mu daješ neki ulazni parametar kad ga pokreneš? Da li treba da pronađe sve fajlove sa jučerašnjim datumom?

Ako mi daš dovoljno informacija, sutra u ovo vreme dobiješ Python skript koji radi posao.
 
Koliko vidim, ovde se ne vrsi bilo kakvo poredjenje trenutnog datuma (i vremena) sa datumom (i vremenom) upisanim u naziv fajla. Odnosno, ne znam da li treba da kopira sve fajlove od prethodnog dana (bez obzira na vreme) ili samo one od prethodnog dana, ali starije od 12h, na primer. Pretpostavljam da je ovo prvo. U tom slucaju mozes da zanemaris vreme upisano u naziv fajla i da koristiš džoker znak posle datuma. Recimo,
file_cert01='CERT_JU_SSIM_'$now'*'
cp source/$file_cert01 destination/
 
Pokusacu da budem jasniji, sad kad citam sta sam prvobitno napisao i sebe sam zbunio :) Elem, svaki dan, u neko vreme (koje varira, moze biti od 00 do 24h, pa cak i vise puta dnevno) stizu fajlovi sa neverovatno inventivnim imenima:

1STS_tvcr291116JU_0823.GPG
1STS_tvcr291116sdJU_0822.GPG
CERT_asr020317_0901.GPG
CERT_sbrtcn020317n_1022.GPG

Skript treba da proveri da li su stigli na SFTP server, dekriptuje ih i prebaci na produkcijski server. U pocetku je zahtev bio da sve to radi automatski, juce po podne mi kazu da ce skript biti pokretan rucno, kako bi se proverilo da li radi kako treba. Ne znam da li ce, kad se ta ekipa uveri da je sa skriptom sve u redu, biti zahteva da se ceo posao automatizuje. Skript treba da nadje sve fajlove sa jucerasnjim datumom i odradi svoje. Onaj koji sam ja napravio je jos i najlaksi, imam ime i datum i to sam sazvakao za pet minuta. Ali sa ovim sam zab'o. Ja nemam nikakvih iskustava sa pisanjem ovakvih skripti (sto nije tesko zakljuciti :) ), radio sam i radim samo skripte za logovanje na kojekave mrezne uredjaje, malo tcl.a na Cisco opremi i to je sve. A uvalise mi patku... Nadam se da sam sad malo jasniji. A tebi hvala do neba sto trosis svoje vreme na mene. Ponudio bih te pivom, ali kako si na Amstelu, nema smisla :)
 
Koliko vidim, ovde se ne vrsi bilo kakvo poredjenje trenutnog datuma (i vremena) sa datumom (i vremenom) upisanim u naziv fajla. Odnosno, ne znam da li treba da kopira sve fajlove od prethodnog dana (bez obzira na vreme) ili samo one od prethodnog dana, ali starije od 12h, na primer. Pretpostavljam da je ovo prvo. U tom slucaju mozes da zanemaris vreme upisano u naziv fajla i da koristiš džoker znak posle datuma. Recimo,
file_cert01='CERT_JU_SSIM_'$now'*'
cp source/$file_cert01 destination/

Problem je sto ovo $now lepi vreme kad skript okine.
 
Sada sam probao i now=$(date -d "1 day ago" +'%Y%m%d') ne lepi vreme. Ne znam zašto bi se dodavalo vreme, kada se ne pominje u formatu?

EDIT:
Ako ime moze da bude bilo šta, ali obavezno sadrži datum negde u sredini, onda staviš ovako nešto

now=$(date -d "1 day ago" +'%Y%m%d')
txtfile='*'$now'*.txt'
gpgfile='*'$now'*.gpg'
allfiles='*'$now'*'

EDIT2:
Vidim da je u svim imenima fajlova datum u obliku DDMMYYYY, pa bi možda trebalo u onom gore formatu zameniti mesta danu i godini.
 
Poslednja izmena:
Opet zbunjujem ljude. Skript koji sam okacio gore radi. Imena fajlova su drugacija i zato ovo date -d "1 day ago" +'%Y%m%d' radi lepo. Pokusao sam to da iskoristim i da na
+'%Y%m%d i dodam %H%M (ovo dodaje i sat i minut) kako bih mogao da radim i sa fajlovima koji se zovu drugacije (1STS_tvcr291116JU_0823.GPG na primer), ali to ne radi.
Ne radi zato sto skript zakuca vreme za ono kad se pokrece, a ne vreme koje se nalazi u imenu fajla.
 
Evo imena fajlova (nisu svi, cisto da vidite nasta ta salata lici :( )

Mar 5 13:00 CERT_SABRE_JU_EMD_USED_20170304.gpg
Mar 6 08:02 sabrejuemd201703040000.txt

Mar 6 13:00 TEST_SABRE_JU_EMD_USED_20170305.gpg
Mar 6 13:00 CERT_SABRE_JU_EMD_USED_20170305.gpg

Mar 6 15:16 CERT_tvcr060317JU_0815.GPG
Mar 6 15:16 CERT_tvcr060317sdJU_0815.GPG
Mar 6 15:50 CERT_xlJU06032017_0849.GPG

Mar 6 15:50 CERT_sbrtcn060317n_0849.GPG
Mar 6 16:01 CERT_asr060317_0900.GPG
Mar 6 17:22 tvcr060317JU.txt
Mar 6 17:23 tvcr060317sdJU.txt
Mar 6 17:23 xlJU06032017.txt

Mar 6 17:24 asr060317.txt
Mar 6 17:26 sabrejuemd201703050000.txt

txt su otpakovani peske.
 
Opet zbunjujem ljude. Skript koji sam okacio gore radi. Imena fajlova su drugacija i zato ovo date -d "1 day ago" +'%Y%m%d' radi lepo. Pokusao sam to da iskoristim i da na
+'%Y%m%d i dodam %H%M (ovo dodaje i sat i minut) kako bih mogao da radim i sa fajlovima koji se zovu drugacije (1STS_tvcr291116JU_0823.GPG na primer), ali to ne radi.
Ne radi zato sto skript zakuca vreme za ono kad se pokrece, a ne vreme koje se nalazi u imenu fajla.
Naravno da ne radi. Ne može skript da izmisli vreme koje je zapisano u imenu fajla. Zbog toga sam i predložio da se koriste džoker znaci, pa da se obuhvati sve što sadrži određeni datum. Jesi li probao tako?
Sada vidimo da je i datum u različitim formatima, što već predstavlja ozbiljan problem, jer ne može uvek jednoznačno da se odredi kada je fajl napravljen. Recimo, ako datum može da bude u obliku YYMMDD i DDMMYY, onda nemaš načina da odrediš tačan datum, jer 170616 može da bude i 16. jun 2017 i 17. jun 2016. Vreme kreiranja fajla bi možda moglo da se dobije od fajl sistema, ali to na Linuxu nije baš uvek izvodljivo.
Možeš li da utičeš na postupak kreiranja imena fajlova?

EDIT:
Ako su ono gore sve moguće varijante za datum, onda je ili YYYYMMDD ili DDMMYY. U tom slučaju je jednostavno sa džoker znacima, samo napraviš dva formata a datum, pa sve operacije obaviš sa oba formata:
datum1=$(date -d "1 day ago" +'%Y%m%d')
datum2=$(date -d "1 day ago" +'%d%m%y')
fn1_1='*'$datum1'*'
fn1_2='*'$datum2'*'
fn2_1='*'$datum1'*.gpg'
fn2_2='*'$datum2'*.gpg'
fn3_1='*'$datum1'*.GPG'
fn3_2='*'$datum2'*.GPG'
 
Poslednja izmena:
Da li je moguce promeniti imena fajlovima? Tj dodati im timestamp?

Ovo ni recima nije jednostavno opisati a kamoli u skriptu ... :)
 
Da li je moguce promeniti imena fajlovima? Tj dodati im timestamp?

Ovo ni recima nije jednostavno opisati a kamoli u skriptu ... :)

npr. cp test.txt test`date +%H_%M_%S`.txt

Obrati paznju na "obrnute" apostrofe. Dodatno, output formate date-a se moze dodatno kontrolisati. Ovde sam stavio samo "hour_minute_second", sa underline-ovima izmedju, radi citljivosti.
 
Da li je moguce promeniti imena fajlovima? Tj dodati im timestamp?

Ovo ni recima nije jednostavno opisati a kamoli u skriptu ... :)

Mislio sam da ime fajla promeni onaj ko je pravio fajl, odnosno ne da promeni, nego da ga napravi na neki unificirani nacin.
 
@gadafi

Probacu ovo, pa javim sta sam uradio. Nije mi palo na pamet...
 
Da li je moguce promeniti imena fajlovima? Tj dodati im timestamp?

Ovo ni recima nije jednostavno opisati a kamoli u skriptu ... :)

Zamisli kako je tek meni... A za rename, opet bi trebalo okinuti neki skript.
 
Mislio sam da ime fajla promeni onaj ko je pravio fajl, odnosno ne da promeni, nego da ga napravi na neki unificirani nacin.

Za ovo tek nema sanse. Fajlove spustaju Ameri, oni su predlozili imena, nasi db admini i biznis korisnici se sa predlogom slozili i sad ja pogiboh.
 
Cini mi se da suvise komplikujes.
Sta se sve nalazi u ulaznom direktorijumu?
Da li smes ulazni fajl da prebacis u drugi direktorijum nakon obrade?
Izlistas sve fajlove u direktorijumu sa gore navedenim ekstenzijama, i u petlji ih procesiras. U svakoj iteraciji, na kraju ulazni fajl prebacis u poddirektorijum i to je to.
INFILES='ls *.gpg *.GPG'
for FILE in $INFILES do
# ovde ide tvoje procesiranje
mv $FILE .. /PROCESSED/
done

Pozdrav
P.S. Treba da bude obrnuti apostrof oko komande ls, ali ga nemam na ovoj tastaturi.
 
Poslednja izmena:
@Gaston:

Meni nije jasno na koji ti nacin "znas" vreme? Tj odakle citas vreme? Iz naziva fajla sa pozicije koja nije jedinstvena?

DiSLOcAtEd je naveo ono sto sam mislio - da se po pristizanju ili obradi uradi dodavanje UNIFICIRANOG timestampa ispred ili iza imena, tebi je posle lako da to obrises ili izmenis ili kako vec.
 
Ma niti on "zna" vreme, niti mu je potrebno da ga zna. Ako sam dobro shvatio, situacija je sledeca:
- U odredjeni direktorijum stizu ulazni fajlovi. Konvencija o imenima fajlova ne postoji, ili postoji ali je on ne zna. Jedino sto se zna je da ime fajla sadrzi datum (u jednom od nekoliko formata) i da fajl ima "ekstenziju" .gpg (case insensitive).
- Potrebno je procesirati ulazne fajlove i rezultat procesiranja poslati na drugi server. Procesiranje je u ovom slucaju dekriptovanje programom gpg. Izlazni fajl treba da ima isto ime kao i ulazni ali sa "ekstenzijom".txt .

- Ako se pretpostavi da fajlovi stizu potpuno nasumicno, i da je moguce ukloniti ulazni fajl nakon obrade, ovo ce biti dovoljno:

# Napravi listu ulaznih fajlova
INFILES = `ls -tr *.gpg *.GPG`


# Petlja po svakom fajlu iz liste
for FILE in $INFILES; do

# Izdvoj ime fajla od ekstenzije - ekstenzija je sve iza poslednje '.'
FILE_NAME="${FILE%.*}"

# Dekriptovanje i ostalo procesiranje
gpg --batch --yes --passphrase $pass -o '/tmp/cpu1/cert/decrypted_cert/'$FILE_NAME.txt --decrypt '/tmp/cpu1/cert/decrypted_cert/'$FILE

# ovde stavi slanje fajla $FILE_NAME.txt
mail .....

# obrisi dekriptovani fajl
rm $FILE_NAME.txt

# Prebaci ulazni fajl u poddirektorijum PROCESSED - da imas arhivu
mv $FILE PROCESSED/$FILE

done

Ovo ce da radi pod nekoliko uslova:
1. Broj ulaznih fajlova nije veci od par desetina hiljada. Ako dobijes gresku "Argument list too long..." onda imas previse ulaznih fajlova i moraces da promenis nacin kako pravis listu ulaznih fajlova, napr:
INFILES = `ls -tr | grep '.gpg$'`

2. Prilikom transfera ulaznog fajla, fajl ima privremeno ime, a tek nakon zavrsetka transfera se preimenuje u konacno ime. Ovo je vazno da se ne bi desilo da gpg krene da procesira fajl koji jos nije prenet u potpunosti. Ako su fajlovi bas mali, ovo nije problem. Ako su veliki ili transfer ide sporo, ovo moze da ti napravi problem.

Pozdrav
 
Ovo što @rafiki kaže skroz ima smisla; premestiš obrađene fajlove na neko drugo mesto, i više ne moraš da razmišljaš o odabiru jučerašnjeg ili današnjeg fajla, niti ti je bitno vreme; obradiš one fajlove koje zatekneš :)
 
Rafiki je bio na najboljem putu osim što ne treba nikada koristiti ls da bi se iteriralo nad određenom grupom fajlova već se odmah koristi globbing

Kod:
#!/bin/bash

gpg="/usr/bin/gpg"
pass="nekipass"
certdir="/tmp/cpu1/cert"

cd "$certdir"

for i in *.gpg *.GPG; do
    echo "$gpg --batch --yes --passphrase $pass -o "$certdir/decrypted/$i.txt" --decrypt "$certdir/$i""
    echo "mv "$i" "$certdir/processed/$i""
done

pre startovanja skripte proveriti sa 'which gpg' gde se nalazi gpg binary i zameniti u skripti punu putanju.
Startovati skriptu i kada se uveriš da radi tačno ono što želiš samo obriši echo i prve i poslednje duple navodnike i to je to.
 
A zasto da se ne koristi ls?
Sa ls imas mogucnost da fajlove obradis po redosledu kreiranja na lokalnom sistemu (ili po nekom drugom), dok bez ls, redosled je uvek po imenu.
Ja sam imao realan slucaj, kada je redosled obrade bio vazan. Bez ls, ne vidim kako bih to postigao.
Pozdrav
 
Pokupi datum, nadji jucerasnji dan i zapisi taj datum u razlicitim formatima.. Npr:
D1 = DDMMYYYY
D2 = DDMMYY
D3 = YYMMDD

u skirpti, pokupi sve fajlove iz foldera, i za svaki fajl trazi da li postoji podstring koji odgovara D1, D2, ili D3. Ukoliko postoji, obradi file i prebaci ga na drugo mesto.
Nije mi jasna cemu onda provera vremena, ako je datum kriterijum za obradu? Zasto uopste proveravas vreme?
 
Poslednja izmena:
Nazad
Vrh Dno