"Összetett" fájlnevek a scriptben

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?

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'

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.

Ú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.

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.

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.

find . -type f -print0 |xargs -0 chmod 0660
vagy:
find . -type f |xargs -i chmod 0660 {}

man find

find . -type f -exec chmod 0660 {} \;

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 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.

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.

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 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."

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 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

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

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 $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