[Bash] 'Net' absoluut pad naar file verkrijgen

Pagina: 1
Acties:

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Topicstarter
Het klinkt heel simpel en dat is het misschien ook, maar te Googlen is het in ieder geval niet.

Ik heb een Bash script dat 1 command line argument mee moet krijgen: een file, waarmee dingen gedaan gaan worden. Ik refereer vaak naar die file als ../foo/bar/interesting_file. Nu wordt er in het script van directory gewisseld, dus ik heb een absoluut pad naar die file nodig, om er later nog aan te kunnen refereren. Nu is dat eenvoudig te doen met
Bash:
1
FILE=`pwd`/${FILE}

maar dat levert paden op als /home/ivo/baz/../foo/bar/interesting_file. Het werkt wel, maar als je de filename nog even ergens echoed, dan is het lelijk. Dus de vraag is simpel:
als ${1} = '../foo/bar/interesting_file', hoe kom ik dan aan het canonieke absolute pad naar 'interesting_file'?

Als het een symlink zou zijn, zou 'readlink' uitkomst brengen en zelf een script schrijven die telkens de .. volgt tot root is ook niet al te moeilijk, maar ik verwacht dat er een eenvoudige manier voor bestaat. Wie? :)

Wie trösten wir uns, die Mörder aller Mörder?


  • blaataaps
  • Registratie: Juli 2001
  • Niet online
readlink -e?
Hoewel -e niet op alle system werkt zo te zien, readlink -f kan ook nog eventueel, als het echt portable moet, moet je vast naar iets als stat gaan kijken denk ik.

[ Voor 88% gewijzigd door blaataaps op 29-08-2007 15:33 ]


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Topicstarter
Ah, readlink werkt ook voor niet-symbolic links... dat had ik niet verwacht. Of wordt een relative references als ../../foo als symbolic link beschouwt?

Wie trösten wir uns, die Mörder aller Mörder?


  • Ivo
  • Registratie: Juni 2001
  • Laatst online: 14-01-2025

Ivo

Splits de niet zo nette url op in relatieve directories. Loop nu door de lijst heen terwijl je telkens naar de nieuwe directory "cd't". Aan het einde van de keten doe je pwd en dan heb je je pad. Is dit simpel genoeg?

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:06

odysseus

Debian GNU/Linux Sid

In Perl kan je het heel simpel doen:
code:
1
perl -e '($_ = "/dit/is/is/../een/test") =~ s/\/[a-z]+\/\.\.//; print'

Dit is absoluut geen mooie code en bevat nogal wat fouten (zoals alleen matchen op kleine letters a-z, niet letten op bijvoorbeeld "..." als directorynaam, etc.), maar in de basis werkt het :). Je kunt het ook simpel nabouwen in sed of awk, mocht je dat liever gebruiken.

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • MrBarBarian
  • Registratie: Oktober 2003
  • Laatst online: 07-03-2023
Ehm, mijn pwd geeft altijd absolute paden:

code:
1
2
3
[user@barbaar etc]$ cd /home/user/tmp/../.ssh/
[user@barbaar .ssh]$ pwd
/home/user/.ssh


of snap ik het nu niet?

Mogelijk een bash-versie issue?

iRacing Profiel


  • u_nix_we_all
  • Registratie: Augustus 2002
  • Niet online
Ja met pwd moet het wel lukken:

code:
1
2
3
4
5
6
fil=`basename $1`
dir=`dirname $1`

newdir=`cd $dir; pwd ; cd - >/dev/null`

filename=$newdir/$fil


zoiets dus ?

You don't need a parachute to go skydiving. You need a parachute to go skydiving twice.


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Topicstarter
Ivo schreef op woensdag 29 augustus 2007 @ 19:30:
Splits de niet zo nette url op in relatieve directories. Loop nu door de lijst heen terwijl je telkens naar de nieuwe directory "cd't". Aan het einde van de keten doe je pwd en dan heb je je pad. Is dit simpel genoeg?
Dat bedoelde ik met "zelf een script schrijven die telkens de .. volgt tot root is ook niet al te moeilijk", maar ik had het idee dat zoiets al moest bestaan. Ik zat net even door de source van readlink (GNU coreutils) te bladeren en hoewel mijn C niet zo sterk is, heb ik het idee dat dat ook zo'n beetje is wat het doet. Het verwijst naar een methode genaamd canonicalize_filename_mode :)

Wie trösten wir uns, die Mörder aller Mörder?


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Topicstarter
MrBarBarian schreef op woensdag 29 augustus 2007 @ 22:19:
Ehm, mijn pwd geeft altijd absolute paden:
Maar als iemand '../foo/file.ext' ingeeft en je doet FILE=`pwd`${1}, dan komen de '..' er logischerwijs wel in terecht. Je kan natuurlijk eerst cd'en naar ${1} en dan pwd geven en `basename ${1}` erachter plakken, maar dat is ook niet echt elegant.

Wie trösten wir uns, die Mörder aller Mörder?


  • MrBarBarian
  • Registratie: Oktober 2003
  • Laatst online: 07-03-2023
Confusion schreef op woensdag 29 augustus 2007 @ 22:33:
[...]

Maar als iemand '../foo/file.ext' ingeeft en je doet FILE=`pwd`${1}, dan komen de '..' er logischerwijs wel in terecht. Je kan natuurlijk eerst cd'en naar ${1} en dan pwd geven en `basename ${1}` erachter plakken, maar dat is ook niet echt elegant.
Ehm, pwd is niet meer dan een echo van PWD (echo $PWD). en die wordt alleen geset na een cd. Zie de bash-manpages.

Dus als er een filename wordt verwacht ga je die sowieso niet vinden met pwd

iRacing Profiel


  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 13:45

deadinspace

The what goes where now?

Confusion schreef op woensdag 29 augustus 2007 @ 22:30:
Dat bedoelde ik met "zelf een script schrijven die telkens de .. volgt tot root is ook niet al te moeilijk", maar ik had het idee dat zoiets al moest bestaan. Ik zat net even door de source van readlink (GNU coreutils) te bladeren en hoewel mijn C niet zo sterk is, heb ik het idee dat dat ook zo'n beetje is wat het doet. Het verwijst naar een methode genaamd canonicalize_filename_mode :)
Hiervoor zit zelfs een functie in de C library genaamd realpath(), dus iets dergelijks moet met een paar regels C wel te maken zijn :P
In Debian zit overigens een programmaatje dat precies dat doet, heel creatief "realpath" genaamd. De beschrijving hint dat je eigenlijk net zo goed readlink kunt gebruiken:
Package: realpath
Priority: optional
Section: utils
Installed-Size: 56
Description: Return the canonicalized absolute pathname
 The package contains a small utility realpath, which converts each
 pathname argument to an absolute pathname, which has no components
 that are symbolic links or the special .  or ..  directory entries.
 .
 This utility provides mostly the same functionality as `/bin/readlink -f'
 in the coreutils package.


Zie verder ook de manpages van realpath (3) en path_resolution (2) :)
Pagina: 1