scripts script resueltos programas programar pasar parametros español ejercicios ejemplos comandos shell unix

resueltos - shell script ejemplos



Unix shell script descubre en qué directorio reside el archivo de script? (15)

BASE_DIR = "$ (cd" $ (dirname "$ 0") "; pwd)"; echo "$ BASEDIR"

Básicamente, necesito ejecutar el script con rutas relacionadas con la ubicación del archivo de script de shell, ¿cómo puedo cambiar el directorio actual al mismo directorio donde reside el archivo de script?


Como sugiere theMarko:

BASEDIR=$(dirname $0) echo $BASEDIR

Esto funciona a menos que ejecute el script desde el mismo directorio donde reside el script, en cuyo caso obtendrá un valor de ''''.

Para solucionar ese problema use:

current_dir=$(pwd) script_dir=$(dirname $0) if [ $script_dir = ''.'' ] then script_dir="$current_dir" fi

Ahora puede usar la variable current_dir a lo largo de su script para referirse al directorio del script. Sin embargo, esto todavía puede tener el problema del enlace simbólico


En Bash, deberías obtener lo que necesitas así:

#!/usr/bin/env bash BASEDIR=$(dirname "$0") echo "$BASEDIR"


Eso debería hacer el truco:

echo `pwd`/`dirname $0`

Puede parecer feo dependiendo de cómo se invocó y del cwd, pero debería llevarlo a donde necesita ir (o puede modificar la cadena si le importa cómo se ve).


Este one-liner le dice dónde está el script de shell, no importa si lo ejecutó o si lo obtuvo . Además, resuelve cualquier enlace simbólico involucrado, si ese es el caso:

dir=$(dirname $(test -L "$BASH_SOURCE" && readlink -f "$BASH_SOURCE" || echo "$BASH_SOURCE"))

Por cierto, supongo que estás usando / bin / bash .



Inspirado por share

read < <(readlink -f $0 | xargs dirname) cd $REPLY


La mejor respuesta para esta pregunta fue respondida aquí:
Obtener el directorio de origen de un script Bash desde dentro

Y es:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

One-liner que le dará el nombre completo del directorio del script, sin importar desde dónde se lo llame.

Para entender cómo funciona puedes ejecutar el siguiente script:

#!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink TARGET="$(readlink "$SOURCE")" if [[ $TARGET == /* ]]; then echo "SOURCE ''$SOURCE'' is an absolute symlink to ''$TARGET''" SOURCE="$TARGET" else DIR="$( dirname "$SOURCE" )" echo "SOURCE ''$SOURCE'' is a relative symlink to ''$TARGET'' (relative to ''$DIR'')" SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located fi done echo "SOURCE is ''$SOURCE''" RDIR="$( dirname "$SOURCE" )" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" if [ "$DIR" != "$RDIR" ]; then echo "DIR ''$RDIR'' resolves to ''$DIR''" fi echo "DIR is ''$DIR''"


La publicación original contiene la solución (ignorar las respuestas, no agregan nada útil). El trabajo interesante lo realiza el mencionado enlace de readlink comandos de Unix con la opción -f . Funciona cuando el script es llamado por un absoluto así como por una ruta relativa.

Para bash, sh, ksh:

#!/bin/bash # Absolute path to this script, e.g. /home/user/bin/foo.sh SCRIPT=$(readlink -f "$0") # Absolute path this script is in, thus /home/user/bin SCRIPTPATH=$(dirname "$SCRIPT") echo $SCRIPTPATH

Para tcsh, csh:

#!/bin/tcsh # Absolute path to this script, e.g. /home/user/bin/foo.csh set SCRIPT=`readlink -f "$0"` # Absolute path this script is in, thus /home/user/bin set SCRIPTPATH=`dirname "$SCRIPT"` echo $SCRIPTPATH

Consulte también: https://.com/a/246128/59087


Si estás usando bash ...

#!/bin/bash pushd $(dirname "${0}") > /dev/null basedir=$(pwd -L) # Use "pwd -P" for the path without links. man bash for more info. popd > /dev/null echo "${basedir}"


Suponiendo que estás usando bash

#!/bin/bash current_dir=$(pwd) script_dir=$(dirname $0) echo $current_dir echo $script_dir

Este script debe imprimir el directorio en el que se encuentra y luego el directorio en el que se encuentra el script. Por ejemplo, cuando lo llama desde / con el script en /home/mez/ , genera

/ /home/mez

Recuerde, cuando asigne variables de la salida de un comando, ajuste el comando en $( y ) , o no obtendrá la salida deseada.


Tantas respuestas, todas plausibles, cada una con objetivos de pros y contras y ligeramente diferentes (lo que probablemente debería indicarse para cada una). Aquí hay otra solución que cumple con el objetivo principal de ser claro y trabajar en todos los sistemas, en todo bash (sin suposiciones sobre las versiones de bash, o las opciones de pwd readlink o pwd ), y razonablemente hace lo que se espera que suceda (por ejemplo, resolviendo enlaces simbólicos). es un problema interesante, pero generalmente no es lo que realmente quiere), manejar casos de borde como espacios en rutas, etc., ignora cualquier error y usa un sano juicio por defecto si hay algún problema.

Cada componente se almacena en una variable separada que puede usar individualmente:

# script path, filename, directory PROG_PATH=${BASH_SOURCE[0]} # this script''s name PROG_NAME=${PROG_PATH##*/} # basename of script (strip path) PROG_DIR="$(cd "$(dirname "${PROG_PATH:-$PWD}")" 2>/dev/null 1>&2 && pwd)"


Un comentario anterior sobre una respuesta lo dijo, pero es fácil perderse entre todas las otras respuestas.

Cuando se utiliza bash:

echo this file: "$BASH_SOURCE" echo this dir: "$(dirname "$BASH_SOURCE")"

Bash Reference Manual, 5.2 Bash Variables


INTRODUCCIÓN

Esta respuesta corrige la respuesta muy rota pero sorprendentemente mejor votada de este hilo (escrito por TheMarko):

#!/usr/bin/env bash BASEDIR=$(dirname "$0") echo "$BASEDIR"

¿POR QUÉ UTILIZAR dirname "$ 0" EN SU PROPIA NO FUNCIONA?

dirname $ 0 solo funcionará si el usuario inicia el script de una manera muy específica. Pude encontrar varias situaciones en las que esta respuesta falla y bloquea el script.

En primer lugar, vamos a entender cómo funciona esta respuesta. Está obteniendo el directorio de script haciendo

dirname "$0"

$ 0 representa la primera parte del comando que llama a la secuencia de comandos (es básicamente el comando ingresado sin los argumentos:

/some/path/./script argument1 argument2

$ 0 = "/ some / path /./ script"

dirname básicamente encuentra el último / en una cadena y lo trunca allí. Así que si lo haces:

dirname /usr/bin/sha256sum

obtendrá: / usr / bin

Este ejemplo funciona bien porque / usr / bin / sha256sum es una ruta con el formato correcto pero

dirname "/some/path/./script"

no funcionaría bien y te daría:

BASENAME="/some/path/." #which would crash your script if you try to use it as a path

Digamos que estás en el mismo directorio que tu script y lo ejecutas con este comando

./script

$ 0 en esta situación será ./script y dirname $ 0 dará:

. #or BASEDIR=".", again this will crash your script

Utilizando:

sh script

Sin ingresar la ruta completa también se dará un BASEDIR = "."

Usando directorios relativos:

../some/path/./script

Da un nombre de directorio $ 0 de:

../some/path/.

Si está en el directorio / some y llama al script de esta manera (tenga en cuenta la ausencia de / al principio, nuevamente una ruta relativa):

path/./script.sh

Obtendrá este valor para dirname $ 0:

path/.

y ./path/./script (otra forma de la ruta relativa) da:

./path/.

Las únicas dos situaciones en las que basedir $ 0 funcionará si el usuario usa sh o touch para iniciar un script porque ambas darán como resultado $ 0:

$0=/some/path/script

lo que te dará una ruta que puedes usar con dirname.

LA SOLUCIÓN

Debería tener en cuenta y detectar cada una de las situaciones mencionadas anteriormente y aplicar una solución si surge:

#!/bin/bash #this script will only work in bash, make sure it''s installed on your system. #set to false to not see all the echos debug=true if [ "$debug" = true ]; then echo "/$0=$0";fi #The line below detect script''s parent directory. $0 is the part of the launch command that doesn''t contain the arguments BASEDIR=$(dirname "$0") #3 situations will cause dirname $0 to fail: #situation1: user launches script while in script dir ( $0=./script) #situation2: different dir but ./ is used to launch script (ex. $0=/path_to/./script) #situation3: different dir but relative path used to launch script if [ "$debug" = true ]; then echo ''BASEDIR=$(dirname "$0") gives: ''"$BASEDIR";fi if [ "$BASEDIR" = "." ]; then BASEDIR="$(pwd)";fi # fix for situation1 _B2=${BASEDIR:$((${#BASEDIR}-2))}; B_=${BASEDIR::1}; B_2=${BASEDIR::2}; B_3=${BASEDIR::3} # <- bash only if [ "$_B2" = "/." ]; then BASEDIR=${BASEDIR::$((${#BASEDIR}-1))};fi #fix for situation2 # <- bash only if [ "$B_" != "/" ]; then #fix for situation3 #<- bash only if [ "$B_2" = "./" ]; then #covers ./relative_path/(./)script if [ "$(pwd)" != "/" ]; then BASEDIR="$(pwd)/${BASEDIR:2}"; else BASEDIR="/${BASEDIR:2}";fi else #covers relative_path/(./)script and ../relative_path/(./)script, using ../relative_path fails if current path is a symbolic link if [ "$(pwd)" != "/" ]; then BASEDIR="$(pwd)/$BASEDIR"; else BASEDIR="/$BASEDIR";fi fi fi if [ "$debug" = true ]; then echo "fixed BASEDIR=$BASEDIR";fi


cd $(dirname $(readlink -f $0))