Kirjoittaja Aihe: millä selvitän onko hakemisto $(pwd) linkitetty johonkin muuallekin? [ratkaistu]  (Luettu 3427 kertaa)

jekku

  • Käyttäjä
  • Viestejä: 2624
    • Profiili
Olisi tehtävä muutama operaatio useassa hakemistossa mutta ohitettava sellaiset jotka linkitetty myös eri nimelle. Milläs kaivelen em. tiedon?

Toisin sanoen, on muutama hakemisto
/mnt/duuni1
/mnt/duuni2
/mnt/duuni3
/mnt/duuni4

ja symbolinen linkki
/mnt/vuorossa -> /mnt/duuni2

Joten silmukassa olisi loikattava tuon /mnt/duuni2 yli.
« Viimeksi muokattu: 21.05.13 - klo:16.55 kirjoittanut jekku »

SuperOscar

  • Käyttäjä
  • Viestejä: 4065
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Äkkiseltään sanoisin, ettet mitenkään. Linkki tietää olevansa linkki, mutta linkin kohde ei tiedä siihen linkatun.

Toisinpäin kuitenkin onnistuu, joten jos tiedät juuren josta etsiä, voisiko hommaa lähestyä näin: jos juuri on esim. /mnt kuten esimerkissäsi,

  • käyt kansion ensin läpi ja keräät kaikki linkit
  • sitten käyt linkit läpi ja keräät niiden kohteet
  • ja lopuksi siinä vaiheessa, kun käyt kansiota työvaiheessa läpi, ohitat löydetyt kohteet
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

jekku

  • Käyttäjä
  • Viestejä: 2624
    • Profiili
Äkkiseltään sanoisin, ettet mitenkään. Linkki tietää olevansa linkki, mutta linkin kohde ei tiedä siihen linkatun.

Toisinpäin kuitenkin onnistuu, joten jos tiedät juuren josta etsiä, voisiko hommaa lähestyä näin: jos juuri on esim. /mnt kuten esimerkissäsi,

  • käyt kansion ensin läpi ja keräät kaikki linkit
  • sitten käyt linkit läpi ja keräät niiden kohteet
  • ja lopuksi siinä vaiheessa, kun käyt kansiota työvaiheessa läpi, ohitat löydetyt kohteet

Nojoo, nuo hakemistot joihin on linkki luulen löytäneeni komennolla

Koodia: [Valitse]
find . -maxdepth 1 -type l  -exec readlink {} \;

Mutta juurikin tuo ohittaminen on nyt hukassa...
« Viimeksi muokattu: 21.05.13 - klo:09.18 kirjoittanut jekku »

SuperOscar

  • Käyttäjä
  • Viestejä: 4065
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Koodia: [Valitse]
find . -maxdepth 1 -type l  -exec readlink {} \;

Eli mennään juuri niin päin kuin sanoinkin: readlink kertoo, mihin annettu linkki viittaa. Nämä voisit nyt kerätä johonkin muuttujaan listaksi ja silmukassa testata, löytyykö kulloinenkin nimi tästä listasta.

Mutta tuota noin... Esimerkkisi oli sen verran simppeli, että olen ehkä ihan metsässä, mutta eikö mielekkäämpää olisi silmukassa testata, onko annettu nimi linkki ja ohittaa se, jos on? Ts. esimerkissäsi ei ohitettaisi kansiota /mnt/duuni2 (koska se on linkin kohde) mutta ohitettaisiinkin sen sijaan /mnt/vuorossa, koska se on linkki kohteeseen /mnt/duuni2.

Muoks: Siis osapuilleen näin:

Koodia: [Valitse]
for f in /mnt/*; do
    [ ! -h $f ] && echo Käsitellään $f...
done

Tuo ”! -h $f” tarkoittaa siis ”jollei $f ole symbolinen linkki”. Hakasulkeet kannattaa korvata kaksoishakasulkeilla, jollei sh-yhteensopivuus ole tärkeää.
« Viimeksi muokattu: 20.05.13 - klo:21.28 kirjoittanut SuperOscar »
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

ajaaskel

  • Palvelimen ylläpitäjä
  • Käyttäjä
  • Viestejä: 3401
    • Profiili
Lainaus
Mutta juurikin tuo ohittaminen on nyt hukassa...

Huutomerkki tai "-not" kääntää merkityksen "find" ssa:

Koodia: [Valitse]
find . -maxdepth 1  ! -type l
tai

Koodia: [Valitse]
find . -maxdepth 1  -not -type l
Tästä jälkimmäisestä find: in manuska sanoo että "ei ole POSIX yhteensopiva".
Autamme ilolla ja ilmaiseksi omalla ajallamme.  Ethän vaadi, uhoa tai isottele näin saamasi palvelun johdosta.

jekku

  • Käyttäjä
  • Viestejä: 2624
    • Profiili
----
Eli mennään juuri niin päin kuin sanoinkin: readlink kertoo, mihin annettu linkki viittaa. Nämä voisit nyt kerätä johonkin muuttujaan listaksi ja silmukassa testata, löytyykö kulloinenkin nimi tästä listasta.

Mutta tuota noin... Esimerkkisi oli sen verran simppeli, että olen ehkä ihan metsässä, mutta eikö mielekkäämpää olisi silmukassa testata, onko annettu nimi linkki ja ohittaa se, jos on? Ts. esimerkissäsi ei ohitettaisi kansiota /mnt/duuni2 (koska se on linkin kohde) mutta ohitettaisiinkin sen sijaan /mnt/vuorossa, koska se on linkki kohteeseen /mnt/duuni2.
----

Arvelin hakevani silmukkaan vain hakemistot, joten /mnt/vuorossa ei edes tule mukaan,
mutta ohittaa pitäisi /mnt/duuni2

Ja siinä kohtaa on musta aukko. Kun ei tule mieleen tarkkaa hakuehtoa listalta/taulukosta joka tarttuisi merkkijonoon /mnt/duuni2 vaan ei reagoisi merkkijonoon /mnt/duuni22 tai /mnt/duuni2138

Edit:

Ja sitten QnD -ratkaisuna

Koodia: [Valitse]
for pd in $(ls)
do
 value=$pd
 if [ -d $value ] # kunhan tarkistan..
 then
   if [[ "${saved_dirs[@]}" =~ "${value} " || "${saved_dirs[${#saved_dirs[@]}-1]}" == "${value}" ]]; then
echo "hakemisto $value on suojattu, loikataan yli"
   else
echo "${value}: Ei suojattu, joten:"
# ja se käsittely tähän...
  fi
fi
done

Nuo ohitettavat on kerätty erikseen tuohon taulukkoon, saved_dirs

« Viimeksi muokattu: 21.05.13 - klo:09.17 kirjoittanut jekku »

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Migreenin keskeltä, vaikka ajatushan ei juokse ja vastaanko edes oikeaan kysymykseen:

Entäpä:
sudo apt-get install symlinks
symlinks -r $(pwd)

SuperOscar

  • Käyttäjä
  • Viestejä: 4065
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Kun ei tule mieleen tarkkaa hakuehtoa listalta/taulukosta joka tarttuisi merkkijonoon /mnt/duuni2 vaan ei reagoisi merkkijonoon /mnt/duuni22 tai /mnt/duuni2138

Entäpä jos sitä saved_dirsiä kävisi läpi for-silmukalla? for’han käy läpi mitä vain välilyönnein erotettua jonoa. Tyyliin (testaamatta):

Koodia: [Valitse]
dont_do_anything=0
for f in *; do
    if [ -d $f ]; then
        for g in ${saved_dirs}; do
            if [ $f = $g ]; then
                dont_do_anything=1
                break # onkokaan sh:ssä breakiä?
            fi
        done
        if [ ${dont_do_anything} -eq 0 ]; then
            # nyt prosessoidaan...
        fi
    fi
done
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

ajaaskel

  • Palvelimen ylläpitäjä
  • Käyttäjä
  • Viestejä: 3401
    • Profiili
En tiedä onko tästä apua mutta taulukkoa ei pysty (?) vertaamaan suoraan vaan vertailu pitää tehdä käymällä silmukalla taulukkoa läpi solu solulta yksi alkio kerrallaan sitä arvoa/merkkijonoa vastaan joka on kyseessä eli tuohon tyyliin kuin "SuperOscar" ehdottaa.
  
Autamme ilolla ja ilmaiseksi omalla ajallamme.  Ethän vaadi, uhoa tai isottele näin saamasi palvelun johdosta.

SuperOscar

  • Käyttäjä
  • Viestejä: 4065
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vähän nätemmän tuosta saisi Pythonilla, mutta kieltämättä Pythonista voi olla komentotulkkiskriptiä vaikeampaa kutsua ulkoisia ohjelmia.

Koodia: [Valitse]
#!/usr/bin/env python

from os import listdir
from os.path import isdir, islink, join

# Edellä annettu muuttujien arvoiksi esim.
# root = '/mnt'
# saved_dirs = ['/mnt/duuni2']

for name in listdir(root):
    path = join(root, name)
    if isdir(path) and not islink(path) and path not in saved_dirs:
        pass    # Tähän prosessointi
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

ajaaskel

  • Palvelimen ylläpitäjä
  • Käyttäjä
  • Viestejä: 3401
    • Profiili
Tuosta saisi rakenteellisesti nätimmän myös bash: llä kun kirjoittaisi erillisen funktion joka tekee vain testauksen.
« Viimeksi muokattu: 21.05.13 - klo:19.05 kirjoittanut ajaaskel »
Autamme ilolla ja ilmaiseksi omalla ajallamme.  Ethän vaadi, uhoa tai isottele näin saamasi palvelun johdosta.

jekku

  • Käyttäjä
  • Viestejä: 2624
    • Profiili
Tuosta saisi rakenteellisesti nätimmän myös bash: llä kun kirjoittaisi erillisen funktion joka tekee vain testauksen.

Asennekysymys.

Jos testiä kutsutaan vain yhdessä kohdassa niin mieluummin kirjoitan sen suoraan siihen kohtaan.
Onpahan helpompaa esim. vuoden kuluttua lukea jotta mitä tulikaan tehtyä ;)

Tosin on monta työkaveria jotka ensi töikseen miettivät millaiset funktiot tarvitaan ja sitten missä järjestyksessä niitä kutsutaan, jos lainkaan ;)