variable una script permanentes entorno declarar crear bash absolute-path

una - variables de entorno linux bash



Expandir una posible ruta relativa en bash (8)

¿Tienes que usar bash exclusivamente? Necesitaba hacer esto y me cansé de las diferencias entre Linux y OS X. Así que usé PHP para una solución rápida y sucia.

#!/usr/bin/php <-- or wherever <?php { if($argc!=2) exit(); $fname=$argv[1]; if(!file_exists($fname)) exit(); echo realpath($fname)."/n"; } ?>

Sé que no es una solución muy elegante, pero funciona.

Como argumentos para mi script, hay algunas rutas de archivos. Esos pueden, por supuesto, ser relativos (o contener ~). Pero para las funciones que he escrito, necesito caminos que sean absolutos, pero que no tengan resueltos sus enlaces simbólicos.

¿Hay alguna función para esto?


Esto me funciona en OS X: $(cd SOME_DIRECTORY 2> /dev/null && pwd -P)

Debería funcionar en cualquier lugar. Las otras soluciones parecían demasiado complicadas.


Simple one-liner:

function abs_path { (cd "$(dirname ''$1'')" &>/dev/null && printf "%s/%s" "$PWD" "${1##*/}") }

Uso:

function do_something { local file=$(abs_path $1) printf "Absolute path to %s: %s/n" "$1" "$file" } do_something $HOME/path/to/some/ where

Todavía estoy tratando de descubrir cómo puedo conseguir que sea completamente ajeno a si la ruta existe o no (para que también se pueda usar al crear archivos).


Tal vez esto sea más legible y no use una subshell y no cambie el directorio actual:

dir_resolve() { local dir=`dirname "$1"` local file=`basename "$1"` pushd "$dir" &>/dev/null || return $? # On error, return error code echo "`pwd -P`/$file" # output full, link-resolved path with filename popd &> /dev/null }


auto edición, me acabo de dar cuenta de que OP dijo que no está buscando enlaces simbólicos resueltos:

"Pero para las funciones que he escrito, necesito caminos que sean absolutos, pero que no tengan sus enlaces simbólicos resueltos".

Así que supongo que esto no es tan apropiado para su pregunta después de todo. :)

Como me he encontrado con esto muchas veces a lo largo de los años, y esta vez necesitaba una versión portátil de bash pura que pudiera usar en OSX y Linux, continué y escribí una:

La versión viva vive aquí:

https://github.com/keen99/shell-functions/tree/master/resolve_path

pero por el bien de SO, aquí está la versión actual (creo que está bien probado ... ¡pero estoy abierto a comentarios!)

Puede que no sea difícil hacer que funcione para bourne shell (sh), pero no lo intenté ... me gusta demasiado $ FUNCNAME. :)

#!/bin/bash resolve_path() { #I''m bash only, please! # usage: resolve_path <a file or directory> # follows symlinks and relative paths, returns a full real path # local owd="$PWD" #echo "$FUNCNAME for $1" >&2 local opath="$1" local npath="" local obase=$(basename "$opath") local odir=$(dirname "$opath") if [[ -L "$opath" ]] then #it''s a link. #file or directory, we want to cd into it''s dir cd $odir #then extract where the link points. npath=$(readlink "$obase") #have to -L BEFORE we -f, because -f includes -L :( if [[ -L $npath ]] then #the link points to another symlink, so go follow that. resolve_path "$npath" #and finish out early, we''re done. return $? #done elif [[ -f $npath ]] #the link points to a file. then #get the dir for the new file nbase=$(basename $npath) npath=$(dirname $npath) cd "$npath" ndir=$(pwd -P) retval=0 #done elif [[ -d $npath ]] then #the link points to a directory. cd "$npath" ndir=$(pwd -P) retval=0 #done else echo "$FUNCNAME: ERROR: unknown condition inside link!!" >&2 echo "opath [[ $opath ]]" >&2 echo "npath [[ $npath ]]" >&2 return 1 fi else if ! [[ -e "$opath" ]] then echo "$FUNCNAME: $opath: No such file or directory" >&2 return 1 #and break early elif [[ -d "$opath" ]] then cd "$opath" ndir=$(pwd -P) retval=0 #done elif [[ -f "$opath" ]] then cd $odir ndir=$(pwd -P) nbase=$(basename "$opath") retval=0 #done else echo "$FUNCNAME: ERROR: unknown condition outside link!!" >&2 echo "opath [[ $opath ]]" >&2 return 1 fi fi #now assemble our output echo -n "$ndir" if [[ "x${nbase:=}" != "x" ]] then echo "/$nbase" else echo fi #now return to where we were cd "$owd" return $retval }

he aquí un ejemplo clásico, gracias a brew:

%% ls -l `which mvn` lrwxr-xr-x 1 draistrick 502 29 Dec 17 10:50 /usr/local/bin/mvn@ -> ../Cellar/maven/3.2.3/bin/mvn

usa esta función y devolverá la ruta real -real:

%% cat test.sh #!/bin/bash . resolve_path.inc echo echo "relative symlinked path:" which mvn echo echo "and the real path:" resolve_path `which mvn` %% test.sh relative symlinked path: /usr/local/bin/mvn and the real path: /usr/local/Cellar/maven/3.2.3/libexec/bin/mvn


en OS X puedes usar

stat -f "%N" YOUR_PATH

en Linux, es posible que tenga el ejecutable realpath . si no, lo siguiente podría funcionar (no solo para enlaces):

readlink -c YOUR_PATH



MY_PATH=$(readlink -f $YOUR_ARG) resolverá rutas relativas como "./" y "../"

Considere esto también ( andy.wordpress.com/2008/05/09/bash-equivalent-for-php-realpath ):

#!/bin/bash dir_resolve() { cd "$1" 2>/dev/null || return $? # cd to desired directory; if fail, quell any error messages but return exit status echo "`pwd -P`" # output full, link-resolved path } # sample usage if abs_path="`dir_resolve /"$1/"`" then echo "$1 resolves to $abs_path" echo pwd: `pwd` # function forks subshell, so working directory outside function is not affected else echo "Could not reach $1" fi