Biztos valami rém egyszerű lehet a megoldás, csak én nem látom :(
Szeretnék egy egyszerű kis scriptet összerakni, ami rekurzívan a kurrens könyvtártól befelé módosítja (csak) a fájlok jogosultságait, mondjuk így:
for item in `ls -R`
do
if [ $item -d]
echo "nem bántjuk: $item"
else
chmod 0660 $item
fi
done
Igen ám, de ha szóköz, vagy pl kapcsos zárójel és egyéb jelek vannak a fájlnévben, akkor annyi "item" lesz egy fájlnévből ahány ilyen karakter van a fájlnévben. Hogy kellene ezt megoldani?
- 4318 megtekintés
Hozzászólások
Nem egy tökéletes megoldás, de hátha segít:
#!/bin/bash
IFS=$'\n'
for item in `find .`
do
if [ -d "$item" ]
then
echo "nem bántjuk: $item"
else
chmod 0660 "$item"
fi
done
IFS=$' \t\n'
- A hozzászóláshoz be kell jelentkezni
"-_[" karaktereket megoldja, de a szóközzel nem tud mit kezdeni :(
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
De.
- A hozzászóláshoz be kell jelentkezni
tipphopp
find . -name "*" | while read filename
do
if [ -d "$filename" ]
echo "nem bántjuk: $filename"
else
chmod 0660 "$filename"
fi
done
mivel a find 1 fájl - 1 sor és a read 1 sor tartalmát rendeli a változóhoz. a loop-on belül pedig szépen idézőjelbe rakva elvileg megeszi a fájlnevet.
nem próbáltam ki, úgy kezelendő!
--
A gyors gondolat többet ér, mint a gyors mozdulat.
- A hozzászóláshoz be kell jelentkezni
Úgy néz ki, hogy eddig ez a legjobb megoldás. Egyedül a kódtábla problémákkal nem tud mit kezdeni (most "en_US.UTF-8" és volt "hu_HU" azaz iso8859-2)
find . -type f -name "*" | while read item
do
echo "item: $item"
chmod 0660 "$item"
done
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
Miert ragaszkodsz a ciklushoz?
Findnel -name "*" szerintem folosleges.
A kodtabla problemak hogyan jelentkeznek?
- A hozzászóláshoz be kell jelentkezni
Igen a "-name" opciót én sem értem ...
Űgy jelentkezik, hogy nem kezeli le, nem történik meg a "chmod", sajnos roppant sok a fájl nehéz elcsípni egy-egy "bakit".
A ciklus azért szeretem, mert könnyebb a hiba keresés, és lehet egyéb "őrültségeket" is tenni, mint egy-egy parancs (pl. átnevezni, egy fájlba kigyűjteni a módosított állományokat stb.).
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
Még egy adalék a kódtáblához - a cirill betűs "Винни-Пух" (ami samba windows alatt tökéletes, és kezelhető) az Linux "ls" eredményeként egy kupac "pikk" jelként jelenik meg a "B - yx" kivételével :) Shellből, nem tudom kezelni :(
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
find . -type f -print0 |xargs -0 chmod 0660
vagy:
find . -type f |xargs -i chmod 0660 {}
- A hozzászóláshoz be kell jelentkezni
Ehhez hasonlót építgettem, de még for ciklussal - így sem kezeli a szóközt :(
for item in `find -type f -print0 | xargs --null ls`
Persze lehet ha az xargs -ra bízzuk a chmod -ot ...
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
A for ciklus nem jo erre, mert az argumentumjait szokozzel "kulonbozteti" meg.
While read -ot kell hasznalni.
- A hozzászóláshoz be kell jelentkezni
Szokoz ellen ez ved:
find . -type f | xargs -d'\n' chmod 0660
- A hozzászóláshoz be kell jelentkezni
man find
find . -type f -exec chmod 0660 {} \;
- A hozzászóláshoz be kell jelentkezni
Ez minden talaltnal execel egy chmodot.
- A hozzászóláshoz be kell jelentkezni
Ciklus esetén is. Amíg nem chmod-on belül oldod meg (chmod * vagy hasonló), addig így is lesz.
- A hozzászóláshoz be kell jelentkezni
find . -type f -print0 | xargs -0 chmod 0660
- A hozzászóláshoz be kell jelentkezni
Igaz :)
- A hozzászóláshoz be kell jelentkezni
Azért nem működik, mert ha szóköz szerepel a fájlnévben, akkor a chmod több paraméterként kapja meg. $item="egy ketto" az a chmodnál már 2 paramétert jelent.
Inkább a find-el próbálkozz.
- A hozzászóláshoz be kell jelentkezni
A file feldolgozast linux alatt a kovetkezo ciklussal illik/kell csinalni:
find . -depth -mount -noleaf -print0 | while read -r -d $'\0' ; do
mycommand "$REPLY"
done
'-depth -mount -noleaf' esetleg nem kell, de a
-print0 ... -d $'\0' kell, valamint a read -nel muszaj a '-r' is.
Itt tehetsz a ciklusmagba ellenorzest, hiba eseten kiirast, amit a 'find -exec' vagy a 'find |xargs' jellegu megoldasokban nem, vagy extrem nehezen. Ez a ciklus mukodik tab, space, ujsor, backslash karakterekre ugyanugyugy, mint a $ ^ ' " ` karakterekre, valamint az osszes latin-* utf* karakterekre.
A tobbi ciklus es megoldas hibas: van olyan filenev, amin elhasal.
Ez a megoldas sem univerzalis, versenyhelyzetben (amikor mas aktivan modosit a directoryban) nem feltetlen jut jo eredmenyre.
- A hozzászóláshoz be kell jelentkezni
Pontosabban gnu find használata esetén.
- A hozzászóláshoz be kell jelentkezni
Meg ezen kívül bash. Mert minthas a read -d máshol nem létezne.
- A hozzászóláshoz be kell jelentkezni
Ott a pont.
- A hozzászóláshoz be kell jelentkezni
ebbol a szalbol is latszik, hogy gnu find, bash parositas nem hatulgombolos wannabe hackerek ertelmetlen funkciohalmozo gyujtemenye, hanem nehany olyan alapveto funkciot tartalmaz, aminek mar 1971-ben is leteznie kellett volna.
nehany :-)
- A hozzászóláshoz be kell jelentkezni
Csak kötözködésképpen, '71-ben még az a mondás járta, hogy a UNIX-ot programozók írták programozóknak; gy. k. ha tudom, hogy problémás lehet a SPACE/TAB/ENTER a fájlnévben, akkor inkább nem használok ilyet, mert kisebb a kényelmetlenség, mint a kár, ami a használatából származhat.
Továbbfejlesztve pedig az is kijön belőle, hogy a GNU-cuccokat pedig felhasználók írják felhasználóknak, akik leszarják az észérveket és logikus magyarázatokat, ha neki seggkitörlős eszköz kell, akkor olyat használ, őt aztán ne korlátozza senik és semmi, nem érdekes, hogy a világ maradék 99%-a beledöglik az ő kényelmébe.
- A hozzászóláshoz be kell jelentkezni
Az állításoddal nem kívánok vitatkozni, mert ez kb. olyan, mintha az isten létéről vitatkoznánk. Viszont az arányokat eltévesztetted. Inkább a világ 99%-a felhasználó, és az 1%-a programozó. A konkrét számokon lehet vitatkozni, de a nagyságrend stimmel. Ráadásul a lényeg az, amennyiben igaz az állításod, hogy a világ 1%-a döglik bele a 99% kényelmébe.
A programozónak ráadásul sokkal nagyobb szabadsága van, mert ha nem tetszik neki a „GNU-cucc”, akkor írhat magának észérvvel megtámogatott programot. De az is lehet hogy már van ilyen nem „GNU-cucc”, akkor pedig csak azt kell használni.
Konkrétabban: A téma indítója nem specifikálta a konkrét futási környezetet, amiben meg akarja oldani a problémát. Így ha „GNU-cuccot” használ, akkor ez neki egy jó megoldás, ha nem azt használ, akkor nyilván jelezni fogja. Más lenne a helyzet, ha a feladat úgy szólna, hogy minden Unix-on, és Unix-szerű OS-en működnie kell a scriptnek.
-----
"Ember embernek farkasa." Ezért aztán "Holló a hollónak nem vájja ki a szemét."
- A hozzászóláshoz be kell jelentkezni
POSIX-nak hívják, amire gondolni tetszik, és igen, ott is meg lehet valósítani. Mint ahogy a bash-ban a másütt igencsak régóta létező két paraméterrel hívott cd parancsot.
- A hozzászóláshoz be kell jelentkezni
A POSIX-ról és annak képességeiről nem állítottam semmit. A „GNU cucc” ellentéteként használtam a „nem GNU cucc”-ot. Ha valami nem GNU cucc, attól még nem biztos, hogy megfelel a POSIX szabványoknak. Azonban van olyan GNU cucc is, ami megfelel a POSIX szabványnak. És mindezek fordítottja is igaz.
-----
"Ember embernek farkasa." Ezért aztán "Holló a hollónak nem vájja ki a szemét."
- A hozzászóláshoz be kell jelentkezni
Erre céloztam: "Más lenne a helyzet, ha a feladat úgy szólna, hogy minden Unix-on, és Unix-szerű OS-en működnie kell a scriptnek"
- A hozzászóláshoz be kell jelentkezni
Tiszteletem!
Témával kapcsolatos lenne a problémám, úgyhogy nem nyitnék új topicot.
Ismerkedem a bash programozás rejtelmeivel, és egy szóközös problémába botlottam.
A helyzet.:
Néhány kritériumnak megfelelő (leginkább méret+kiterjesztés) file-okat keresek pár felmountolt (cifs) meghajtón, ezek összesen kb. 1TByte méretűek, elnevezésben teljesen vegyes felvágott, szóköz, ékezet, ()-jel elég sűrűn előfordul mappa és file nevekben.
find /mnt/adat/Files -iname *.$kit1 -a -size $mer1 -o -iname *.$kit2 -a -size $mer2 -o -iname *.$kit3 -a -size $mer3 -o -iname *.$kit4 -a -size $mer4 -o -iname *.$kit5 -a -size $mer5 -o -iname *.$kit6 -a -size $mer6 >> $path/$dat/$filenev1
temp1=$(cat $path/$dat/$filenev1)
du --si $temp1 > $path/$dat/123.doc
A teszt környezetemben (ékezet és egyéb nélkül) remekül megy. Élesben, a szóköznél a du elakad, hogy nem talált ilyen-olyan mappát. De hát hogy is találna, hisz nincs.
Gondolom, a feldolgozás során, amielőtt is a $filenev1-be kerülne a find kimenete, akkor kellene valamit tennem. De mit?
Megj.:
Van úgy, hogy ezt dobálja, gondolom a célgépek terhelése végett.:
CIFS VFS: No response for cmd XX mid XXXX
Köszönöm!
-----------------------------------------
Linux alapparancsok, kezdőknek
- A hozzászóláshoz be kell jelentkezni
Elsőre itt is az említett IFS-sel próbálkoznék.
- A hozzászóláshoz be kell jelentkezni
A szóköz terminálja a paramétereket, így a helyettesítéseket rakd idézőjelek közé:
files='a1.txt b2.txt'
cat $files >kimenet
Ez összefűzi kimenetbe a1.txt-t és b2.txt-t, mert a cat két paramétert kap. A szóköz szeparálja a paramétereket.
files='a1.txt b2.txt'
cat "$files" >kimenet
Ez a "a1.txt b2.txt" nevű - a névnek az idézőjelek nem részei - file-t másolja a kimenetbe.
tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Ezt eddig nem tudtam, hasznos infó köszönöm.
A változtatásom ennyi (,ha jól vettem a felém irányuló infókat).:
du --si "$temp1" > $path/$dat/123.doc
Így annyi a változás, hogy a $temp1-ben lévő adatot egy darab elérési útnak nézi. (ami kezdésnek jó!)
De az én hasznos adatom, kb 300 darab találat, soronként 1-1 teljes elérési útvonallal és file névvel.
Tehát a du ismét nem talál olyan file-t (igaz csak 1-et keresésenként), ami kb 4000 karakter hosszú és az összes találat nevű.! :)
Köszönöm!
udv
letix
update.:
Megpróbálom valahogy kinyerni a file-okból egy for ciklussal soronként az adatokat.
-----------------------------------------
Linux alapparancsok, kezdőknek
- A hozzászóláshoz be kell jelentkezni
Nyilván soronként kell kinyerned az adatokat. Erre jó lehet egy ciklus. Ha jól értem, temp1 változóban vannak a filenevek. Ekkor bash-ben például:
while read; do
du --si "$REPLY"
done <<<"$temp1" >"$path/$dat/123.doc"
tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Egyébként minek a temp1, ha már file-ban ott a lista?
while read; do
du --si "$REPLY"
done <"$path/$dat/$filenev1" >"$path/$dat/123.doc"
tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A $temp változó csupán a hozzá-nem-értésemből fakadó fölösleges lépés volt, töröltem! :)
Gyönyörűen működik, hál istennek egyéb spec. karakterek egyelőre nem zavarnak be.
Köszönöm szépen, sokat segítettél az idézőjelek szemléltető bemutatásával, valamint a $REPLY belső változóval!
udv
letix
-----------------------------------------
Linux alapparancsok, kezdőknek
- A hozzászóláshoz be kell jelentkezni
A ciklusmag utolsó sorába akár egy ilyet is írhatsz, hogy elszeparálja a du kimeneteit a jobb olvashatóság kedvéért:
echo '-----------------------------'
tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni