¿Cómo obtendría solo el nombre del directorio de trabajo actual en un script bash, o incluso mejor, solo un comando de terminal?
pwd
da la ruta completa del directorio de trabajo actual, por ejemplo, /opt/local/bin
pero solo quierobin
¿Cómo obtendría solo el nombre del directorio de trabajo actual en un script bash, o incluso mejor, solo un comando de terminal?
pwd
da la ruta completa del directorio de trabajo actual, por ejemplo, /opt/local/bin
pero solo quierobin
Respuestas:
No necesita basename, y especialmente no necesita una subshell que ejecute pwd (que agrega una operación de horquilla adicional y costosa ); el shell puede hacer esto internamente usando la expansión de parámetros :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
Tenga en cuenta que si está aplicando esta técnica en otras circunstancias (no PWD
, pero alguna otra variable que contenga un nombre de directorio), es posible que deba recortar las barras diagonales finales. A continuación se utiliza el soporte extglob de bash para trabajar incluso con múltiples barras diagonales:
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
Alternativamente, sin extglob
:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWD
es el nombre de una variable bash incorporada; Todos los nombres de variables incorporados están en mayúsculas (para distinguirlos de las variables locales, que siempre deben tener al menos un carácter en minúscula). result=${PWD#*/}
Cómo no valorar a /full/path/to/directory
; en su lugar, despoja solo el primer elemento, haciéndolo path/to/directory
; El uso de dos #
caracteres hace que el patrón coincida con la codicia, haciendo coincidir tantos caracteres como sea posible. Lea la página de expansión de parámetros, vinculada en la respuesta, para más información.
pwd
no siempre es el mismo que el valor de $PWD
, debido a las complicaciones que surgen de cd
la conexión a través de enlaces simbólicos, si bash tiene la -o physical
opción establecida, etc. Esto solía volverse especialmente desagradable en el manejo de directorios montados automáticamente, donde grabar la ruta física en lugar de la lógica produciría una ruta que, si se usa, permitiría al automontador desmontar espontáneamente el directorio que estaba usando.
sh
y csh
y si queríamos la tecla de retroceso para trabajar había que leer toda la stty
página hombre, y nos gustó!"
Usa el basename
programa. Para su caso:
% basename "$PWD"
bin
basename
programa? ¿Qué hay de malo en esta respuesta además de faltar las comillas?
basename
es de hecho un programa externo que hace lo correcto, pero el funcionamiento de cualquier programa externo para una fiesta que se puede hacer fuera de la caja utilizando solamente funcionalidad integrada es tonto, incurriendo impacto en el rendimiento ( fork()
, execve()
, wait()
, etc.) para Sin razón.
basename
aquí no se aplican dirname
, porque dirname
tiene una funcionalidad que ${PWD##*/}
no lo hace, transformando una cadena sin barras .
, por ejemplo. Por lo tanto, si bien el uso dirname
como herramienta externa tiene una sobrecarga de rendimiento, también tiene una funcionalidad que ayuda a compensarlo.
function
palabra clave es incompatible con POSIX sin agregar ningún valor sobre la sintaxis estandarizada, y la falta de comillas crearía errores en los nombres de directorio con espacios. wdexec() { "./$(basename "$PWD")"; }
podría ser una alternativa preferible.
basename
es menos "eficiente". Pero probablemente sea más eficiente en términos de productividad del desarrollador porque es fácil de recordar en comparación con la sintaxis de bash feo. Entonces, si lo recuerdas, hazlo. De lo contrario, basename
funciona igual de bien. ¿Alguien ha tenido que mejorar el "rendimiento" de un script bash y hacerlo más eficiente?
$ echo "${PWD##*/}"
echo "${PWD##*/}"
.
name=${PWD##*/}
sería correcto y name=$(echo "${PWD##*/}")
sería incorrecto (en un sentido de ineficiencia innecesaria).
Puede usar una combinación de pwd y basename. P.ej
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Me gusta la respuesta seleccionada (Charles Duffy), pero tenga cuidado si está en un directorio con enlace simbólico y desea el nombre del directorio de destino. Desafortunadamente, no creo que se pueda hacer en una expresión de expansión de un solo parámetro, tal vez me equivoque. Esto debería funcionar:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Para ver esto, un experimento:
cd foo
ln -s . bar
echo ${PWD##*/}
informa "bar"
Para mostrar los directorios iniciales de una ruta (sin incurrir en un fork-exec de / usr / bin / dirname):
echo ${target_PWD%/*}
Esto, por ejemplo, transformará foo / bar / baz -> foo / bar
readlink -f
es una extensión de GNU y, por lo tanto, no está disponible en los BSD (incluido OS X).
echo "$PWD" | sed 's!.*/!!'
Si está utilizando Bourne Shell o ${PWD##*/}
no está disponible.
${PWD##*/}
es POSIX sh: todo moderno / bin / sh (incluido el tablero, ceniza, etc.) lo admite; para llegar a Bourne real en una caja reciente, necesitarías estar en un sistema Solaris ligeramente antiguo. Más allá de eso - echo "$PWD"
; omitir las comillas conduce a errores (si el nombre del directorio tiene espacios, caracteres comodín, etc.).
Sorprendentemente, nadie mencionó esta alternativa que usa solo comandos bash incorporados:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Como una ventaja adicional , puede obtener fácilmente el nombre del directorio principal con:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Estos funcionarán en Bash 4.3-alpha o más reciente.
Utilizar:
basename "$PWD"
O
IFS=/
var=($PWD)
echo ${var[-1]}
Convierta el separador de nombre de archivo interno (IFS) de nuevo al espacio.
IFS=
Hay un espacio después del IFS.
basename $(pwd)
o
echo "$(basename $(pwd))"
pwd
se divide en cadenas y se expande globalmente antes de pasar a basename
.
basename "$(pwd)"
aunque eso es muy ineficiente en comparación con solo basename "$PWD"
, lo que en sí mismo es ineficiente en comparación con el uso de una expansión de parámetros en lugar de llamar basename
en absoluto.
Para los jinetes de búsqueda como yo:
find $PWD -maxdepth 0 -printf "%f\n"
$PWD
a "$PWD"
para manejar correctamente los nombres de directorio inusuales.
generalmente uso esto en scripts sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
puedes usar esto para automatizar cosas ...
Debajo de grep con regex también funciona,
>pwd | grep -o "\w*-*$"
Solo usa:
pwd | xargs basename
o
basename "`pwd`"
xargs
formulación es ineficaz y tiene errores cuando los nombres de directorio contienen nuevas líneas literales o caracteres de comillas, y la segunda formulación llama al pwd
comando en una subshell, en lugar de recuperar el mismo resultado a través de una expansión variable incorporada.
Si desea ver solo el directorio actual en la región de solicitud de bash, puede editar el .bashrc
archivo ~
. Cambiar \w
a \W
en la línea:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
correr source ~/.bashrc
y solo mostrará el nombre del directorio en la región de solicitud.
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Prefiero usar gbasename
, que es parte de GNU coreutils.
basename
allí. Por lo general, solo se llama gbasename
en MacOS y otras plataformas que de lo contrario se envían con un nombre base no GNU.
Los siguientes comandos darán lugar a la impresión de su directorio de trabajo actual en un script bash.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1
contendrá el directorio de trabajo actual. (2) El pushd
y popd
no sirve para nada aquí porque cualquier cosa dentro de los backticks se realiza en una subshell, por lo que no puede afectar el directorio del shell principal para empezar. (3) El uso "$(cd "$1"; pwd)"
sería más legible y resistente frente a los nombres de directorio con espacios en blanco.