y la variante que estoy usando para obtener el padre del directorio de trabajo actual: parentdir=$(dirname `pwd`)
TheGrimmScientist
3
Tenga en cuenta que este método no es seguro para los nombres "feos". Un nombre como "-rm -rf" romperá el comportamiento deseado. Probablemente "." también lo hará. No sé si esa es la mejor manera, pero he creado una pregunta separada "centrada en la corrección" aquí: stackoverflow.com/questions/40700119/…
VasiliNovikov
44
@Christopher Shroba Sí, omití las citas y luego mi HDD terminó parcialmente borrado. No recuerdo exactamente lo que sucedió: presumiblemente un directorio de espacios en blanco sin comillas hizo que borrara el directorio principal en lugar del de destino; mi script simplemente borró la carpeta / home / xxx /.
catamphetamine
3
oh, está bien, así que no hay nada sobre el comando que pueda hacer que se pierdan datos a menos que ya esté emitiendo un comando de eliminación, ¿verdad? ¿Era solo una cuestión de la ruta que estabas tratando de eliminar dividiéndote en un personaje espacial y eliminando mucho más de lo esperado?
Christopher Shroba
18
... pero lo que se "ve aquí " está roto. Aquí está la solución:
Solo utilícelo echo $(cd ../ && pwd)mientras trabaja en el directorio cuyo directorio principal desea averiguar. Esta cadena también tiene el beneficio adicional de no tener barras diagonales finales.
El uso evalNO es excelente si hay alguna posibilidad de analizar la entrada del usuario que podría ubicarlo en un lugar que no espera o ejecutar cosas malas contra su sistema. ¿Se puede usar en pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nulllugar de la eval?
dragon788
2
No necesitas evalnada: solo hazlo parentdir=$(cd -- "$dir" && pwd). Como cdse ejecuta en una subshell, no es necesario cdvolver a donde estábamos. El --está aquí en caso de que la expansión de $dircomience con un guión. Esto &&es solo para evitar parentdirtener un contenido no vacío cuando cdno tuvo éxito.
gniourf_gniourf
8
Motivación por otra respuesta
Me gusta el código muy corto, claro y garantizado. Punto de bonificación si no ejecuta un programa externo, ya que el día que necesite procesar una gran cantidad de entradas, será notablemente más rápido.
Principio
No estoy seguro de qué garantías tiene y quiere, por lo que ofrece de todos modos.
Si tiene garantías, puede hacerlo con un código muy corto. La idea es usar la función de sustitución de texto bash para cortar la última barra y lo que sigue.
Responda de casos simples a más complejos de la pregunta original.
Si se garantiza que la ruta finalizará sin barra inclinada (entrada y salida)
Si la ruta de entrada puede terminar con cero o una barra inclinada (no más) y desea que la ruta de salida termine sin barra inclinada
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/do
P_ENDNOSLASH="${P%/}"; echo "${P_ENDNOSLASH%/*}"done/home/smith/Desktop/home/smith/Desktop
Si la ruta de entrada puede tener muchas barras extrañas y desea que la ruta de salida finalice sin barra
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";done/home/smith/Desktop/home/smith/Desktop/home/smith/Desktop
Fantástica respuesta. Dado que parece que estaba buscando una forma de hacerlo desde un script (encuentre el directorio actual del script y su padre y haga algo en relación con el lugar donde vive el script), esta es una gran respuesta y puede tener aún más control sobre si la entrada tiene una barra inclinada final o no mediante el uso de expansión de parámetros contra la ${BASH_SOURCE[0]}cual sería la ruta completa al script si no se obtuvo a través de sourceo ..
lo siento, quiero decir, como un script bash, tengo una variable con la ruta del archivo
YTKColumba
Ejecutar ese código me da el error bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). El código vinculado también está mal.
Michael Hoffman
intente simplemente ejecutar dirname Testdesde el directorio Testestá en.
Jon Egeland
1
Dependiendo de si necesita rutas absolutas, es posible que desee dar un paso adicional:
local lookFor_ parent_ switch_ i_
lookFor_="$1"#if it is not a file, we need the grand parent[-f "$lookFor_"]|| switch_="/.."#length of search string
i_="${#lookFor_}"#remove string one by one until it make sens for the systemwhile["$i_"-ge 0]&&[!-d "${lookFor_:0:$i_}"];do
let i_--done#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
Si por cualquier razón usted está interesado en la navegación de un número específico de directorios también se puede hacer: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Esto daría 3 directorios de padres arriba
..
', pero tal vez eso no sea exactamente lo que tenía en mente.Respuestas:
Funciona si también hay una barra inclinada final.
fuente
parentdir=$(dirname `pwd`)
... pero lo que se "ve aquí " está roto. Aquí está la solución:
fuente
Solo utilícelo
echo $(cd ../ && pwd)
mientras trabaja en el directorio cuyo directorio principal desea averiguar. Esta cadena también tiene el beneficio adicional de no tener barras diagonales finales.fuente
echo
aquí.Claramente, el directorio principal se proporciona simplemente agregando el nombre de archivo punto-punto:
Pero debe querer la ruta resuelta (una ruta absoluta sin ningún componente de ruta punto-punto):
El problema con las respuestas principales que usan
dirname
es que no funcionan cuando ingresas una ruta con puntos-puntos:Esto es más poderoso :
Puede alimentarlo
/home/smith/Desktop/Test/..
, pero también rutas más complejas como:EDITAR: Si no funciona, verifique que
cd
no se haya modificado, como a veces es una práctica común,fuente
eval
NO es excelente si hay alguna posibilidad de analizar la entrada del usuario que podría ubicarlo en un lugar que no espera o ejecutar cosas malas contra su sistema. ¿Se puede usar enpushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
lugar de laeval
?eval
nada: solo hazloparentdir=$(cd -- "$dir" && pwd)
. Comocd
se ejecuta en una subshell, no es necesariocd
volver a donde estábamos. El--
está aquí en caso de que la expansión de$dir
comience con un guión. Esto&&
es solo para evitarparentdir
tener un contenido no vacío cuandocd
no tuvo éxito.Motivación por otra respuesta
Me gusta el código muy corto, claro y garantizado. Punto de bonificación si no ejecuta un programa externo, ya que el día que necesite procesar una gran cantidad de entradas, será notablemente más rápido.
Principio
No estoy seguro de qué garantías tiene y quiere, por lo que ofrece de todos modos.
Si tiene garantías, puede hacerlo con un código muy corto. La idea es usar la función de sustitución de texto bash para cortar la última barra y lo que sigue.
Responda de casos simples a más complejos de la pregunta original.
Si se garantiza que la ruta finalizará sin barra inclinada (entrada y salida)
Si se garantiza que la ruta finalizará exactamente con una barra (entrada y salida)
Si la ruta de entrada puede terminar con cero o una barra inclinada (no más) y desea que la ruta de salida termine sin barra inclinada
Si la ruta de entrada puede tener muchas barras extrañas y desea que la ruta de salida finalice sin barra
fuente
${BASH_SOURCE[0]}
cual sería la ruta completa al script si no se obtuvo a través desource
o.
.Si
/home/smith/Desktop/Test/../
es lo que quieres:como se ve aquí .
fuente
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. El código vinculado también está mal.dirname Test
desde el directorioTest
está en.Dependiendo de si necesita rutas absolutas, es posible que desee dar un paso adicional:
fuente
usa esto:
export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
si quieres el 4to directorio padreexport MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
si quieres el tercer directorio padreexport MYVAR="$(dirname "$(dirname $PWD)")"
si quieres el segundo directorio padrefuente
feo pero eficiente
{
}
fuente
Comenzó a partir de la idea / comentario Charles Duffy - 17 de diciembre de 2014 a las 5:32 sobre el tema Obtener el nombre del directorio actual (sin ruta completa) en un script Bash
fuente
Si por cualquier razón usted está interesado en la navegación de un número específico de directorios también se puede hacer:
nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Esto daría 3 directorios de padres arribafuente