2008-10-16 19 views
13

Estoy convirtiendo algunos archivos por lotes de Windows en scripts de Unix usando sh. Tengo problemas porque algún comportamiento depende de la macro% ~ dp0 disponible en los archivos por lotes.Equivalente a% ~ dp0 en sh

¿Hay alguna sh equivalente a esto? ¿Alguna forma de obtener el directorio donde vive el script de ejecución?

+0

parece el diseño de fiesta esta característica no era una preocupación para ir a ... – n611x007

Respuesta

1

Sí, puedes! Está en los argumentos. :)

vistazo a

${0} 

combinando eso con

{$var%Pattern} 
Remove from $var the shortest part of $Pattern that matches the back end of $var. 

lo que quiere es sólo

${0%/*} 

recomiendo el Advanced Bash Scripting Guide (que es también el lugar donde la información anterior es desde). Especialmente la parte en Converting DOS Batch Files to Shell Scripts puede ser útil para usted. :)

Si te he entendido mal, es posible que tengas que combinar eso con la salida de "pwd". ¡Ya que solo contiene la ruta con la que se llamó el script! Prueba la siguiente secuencia de comandos:

#!/bin/bash 
called_path=${0%/*} 
stripped=${called_path#[^/]*} 
real_path=`pwd`$stripped 
echo "called path: $called_path" 
echo "stripped: $stripped" 
echo "pwd: `pwd`" 
echo "real path: $real_path 

Esto necesita un poco de trabajo, sin embargo. Recomiendo usar el enfoque de Dave Webb a menos que eso sea imposible.

-1

Prueba esto:

${0%/*} 
0

He tratado de $ en 0 antes, a saber: ""

nombredir $ 0

y simplemente devuelve incluso cuando el script se está obteniendo de otra secuencia de comandos:

. ../somedir/somescript.sh

+0

puede publicar el guión exacto que ha intentado? o un ejemplo – Sarien

6

El problema (para usted) con $0 es que se establece en la línea de comandos lo fue el uso de invocar el guión, no la ubicación del script mismo. Esto puede hacer que sea difícil obtener la ruta completa del directorio que contiene la secuencia de comandos, que es lo que obtiene de %~dp0 en un archivo por lotes de Windows.

Por ejemplo, considere la siguiente secuencia de comandos, dollar.sh:

#!/bin/bash 
echo $0 

Si desea ejecutarlo obtendrá el siguiente resultado:

# ./dollar.sh 
./dollar.sh 
# /tmp/dollar.sh 
/tmp/dollar.sh 

Así que para obtener el nombre de directorio totalmente calificado de un script que hago lo siguiente:

cd `dirname $0` 
SCRIPTDIR=`pwd` 
cd - 

Esto funciona de la siguiente manera:

  1. cd al directorio de la secuencia de comandos, utilizando la ruta relativa o absoluta desde la línea de comandos.
  2. Obtiene la ruta absoluta de este directorio y la almacena en SCRIPTDIR.
  3. Vuelve al directorio de trabajo anterior con "cd -".
+1

Si no es deseable cambiar el directorio de trabajo, agregué otro appraoch. – Sarien

+2

El script está en la ruta y no se llama directamente, entonces $ 0 será solo el nombre del script y este método no funcionará. –

+0

Así que llama a 'que' también, y resuelve el problema. (que le indica la ruta completa a un comando, pero lo que la mayoría de la gente no parece saber es que retoma la ruta completa si ya es absoluta). – Trejkaz

2

yo estaba tratando de encontrar el camino para un guión que estaba siendo originario de otro guión. Y ese fue mi problema, cuando el origen del texto simplemente se copia en el script de llamada, por lo que $ 0 siempre devuelve información sobre el script de llamada.

Encontré una solución, que solo funciona en bash, $ BASH_SOURCE siempre tiene la información sobre la secuencia de comandos a la que se hace referencia. Incluso si el script tiene origen, se resuelve correctamente en el script original (de origen).

2

En bash en Linux se puede obtener la ruta completa al comando con:

readlink /proc/$$/fd/255 

y para obtener el directorio:

dir=$(dirname $(readlink /proc/$$/fd/255)) 

Es feo, pero todavía tengo que encontrar otra manera .

+0

podría ampliar la explicación sobre por qué es mejor que otras respuestas propuestas en el caso cuando el script está en la ruta y, por lo tanto, se llama indirectamente, y cómo funciona, de qué depende (espero cosas como '$$' de bash, y un sistema de archivos Unix, tenga en cuenta que hay bash en cygwin o mingw que se puede iniciar sin una estructura de sistema de archivos compatible con posix en la mano)? – n611x007

0

Esto debería funcionar para la cáscara del golpe: la escritura

dir=$(dirname $(readlink -m $BASH_SOURCE)) 

prueba:

#!/bin/bash 
echo $(dirname $(readlink -m $BASH_SOURCE)) 

Ejecutar prueba:

$ ./somedir/test.sh 
/tmp/somedir 
$ source ./somedir/test.sh 
/tmp/somedir 
$ bash ./somedir/test.sh 
/tmp/somedir 
$ . ./somedir/test.sh 
/tmp/somedir 
1

La respuesta correcta es la siguiente: How do I determine the location of my script? I want to read some config files from the same place.

Es importante tener en cuenta que en el caso general, este problema no tiene solución. Cualquier enfoque del que pueda haber oído hablar, y cualquier enfoque que se detallará a continuación, tiene fallas y solo funcionará en casos específicos. En primer lugar, trate de evitar el problema por completo, no dependiendo de la ubicación de su script.

Antes de sumergirnos en las soluciones, aclaremos algunos malentendidos. Es importante comprender que: ¡Su secuencia de comandos en realidad no tiene una ubicación!De donde provengan los bytes, , no existe una "ruta canónica" para ello. Nunca. $ 0 NO es la respuesta a su problema. Si crees que es así, puedes dejar de leer y escribir más errores, o puedes aceptar esto y seguir leyendo. ...