Come avrei ottenuto solo il nome della directory di lavoro corrente in uno script bash, o meglio, solo un comando terminale.
pwd
fornisce il percorso completo della directory di lavoro corrente, ad esempio, /opt/local/bin
ma voglio solobin
Come avrei ottenuto solo il nome della directory di lavoro corrente in uno script bash, o meglio, solo un comando terminale.
pwd
fornisce il percorso completo della directory di lavoro corrente, ad esempio, /opt/local/bin
ma voglio solobin
Risposte:
Non è necessario il nome di base, e in particolare la necessità di una subshell che esegue pwd (che aggiunge un'operazione fork extra e costosa ); la shell può farlo internamente usando l' espansione dei parametri :
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.
Nota che se stai applicando questa tecnica in altre circostanze (no PWD
, ma qualche altra variabile con un nome di directory), potresti aver bisogno di tagliare eventuali barre finali. Di seguito viene utilizzato il supporto extglob di bash per funzionare anche con più barre finali:
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"
In alternativa, senza extglob
:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWD
è il nome di una variabile bash incorporata; tutti i nomi delle variabili incorporate sono in maiuscolo (per distinguerli dalle variabili locali, che devono sempre avere almeno un carattere minuscolo). result=${PWD#*/}
fa non valutare a /full/path/to/directory
; invece, rimuove solo il primo elemento, rendendolo path/to/directory
; l'uso di due #
caratteri rende il modello corrispondente avido, abbinando il maggior numero possibile di caratteri. Leggi la pagina di espansione dei parametri, collegata nella risposta, per ulteriori informazioni.
pwd
non è sempre lo stesso del valore di $PWD
, a causa delle complicazioni derivanti dall'ing cd
tramite collegamenti simbolici, se bash ha l' -o physical
opzione impostata e così via. Questo era particolarmente brutto nella gestione delle directory montate automaticamente, in cui la registrazione del percorso fisico anziché quello logico avrebbe prodotto un percorso che, se usato, avrebbe permesso all'automounter di smontare spontaneamente la directory che stava usando.
sh
e csh
e se volevi che la chiave di backspace funzionasse, dovevi leggere l'intera stty
pagina man e ci piaceva!"
Usa il basename
programma. Per il tuo caso:
% basename "$PWD"
bin
basename
programma? Cosa c'è di sbagliato in questa risposta oltre a perdere le virgolette?
basename
è davvero un programma esterno che fa la cosa giusta, ma in esecuzione alcun programma esterno per un bash cosa può fare out-of-the-box, utilizzando solo funzionalità built-in è sciocco, incorrere impatto sulle prestazioni ( fork()
, execve()
, wait()
, ecc) per nessuna ragione.
basename
qui non si applicano dirname
, perché dirname
ha funzionalità che ${PWD##*/}
non lo fanno - trasformando una stringa senza barre .
, per esempio. Pertanto, mentre l'utilizzo dirname
come strumento esterno ha un sovraccarico di prestazioni, ha anche funzionalità che aiutano a compensare lo stesso.
function
parola chiave è incompatibile con POSIX senza aggiungere alcun valore sulla sintassi standardizzata e la mancanza di virgolette creerebbe bug nei nomi di directory con spazi. wdexec() { "./$(basename "$PWD")"; }
potrebbe essere un'alternativa preferibile.
basename
è meno "efficiente". Ma è probabilmente più efficiente in termini di produttività degli sviluppatori perché è facile da ricordare rispetto alla brutta sintassi bash. Quindi, se lo ricordi, fallo. Altrimenti, basename
funziona altrettanto bene. Qualcuno ha mai dovuto migliorare le "prestazioni" di uno script bash e renderlo più efficiente?
$ echo "${PWD##*/}"
echo "${PWD##*/}"
.
name=${PWD##*/}
sarebbe giusto e name=$(echo "${PWD##*/}")
sarebbe sbagliato (in senso inutile inefficienza).
Puoi usare una combinazione di pwd e basename. Per esempio
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Mi piace la risposta selezionata (Charles Duffy), ma fai attenzione se ti trovi in una directory con collegamento simbolico e desideri il nome della directory di destinazione. Sfortunatamente non penso che possa essere fatto in una singola espressione di espansione dei parametri, forse mi sbaglio. Questo dovrebbe funzionare:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Per vedere questo, un esperimento:
cd foo
ln -s . bar
echo ${PWD##*/}
riporta "bar"
Per mostrare le directory principali di un percorso (senza incorrere in un fork-exec di / usr / bin / dirname):
echo ${target_PWD%/*}
Questo ad esempio trasformerà foo / bar / baz -> foo / bar
readlink -f
è un'estensione GNU e quindi non disponibile sui BSD (incluso OS X).
echo "$PWD" | sed 's!.*/!!'
Se si utilizza la shell Bourne o ${PWD##*/}
non è disponibile.
${PWD##*/}
è POSIX sh - ogni moderno / bin / sh (compresi trattini, ceneri, ecc.) Lo supporta; per colpire il vero Bourne su un recente box, dovresti trovarti su un sistema Solaris leggermente vecchio. Oltre a ciò - echo "$PWD"
; tralasciando le virgolette si ottengono bug (se il nome della directory ha spazi, caratteri jolly, ecc.).
Sorprendentemente, nessuno ha menzionato questa alternativa che utilizza solo i comandi bash integrati:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Come bonus aggiuntivo puoi facilmente ottenere il nome della directory principale con:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Questi funzioneranno su Bash 4.3-alpha o più recenti.
Uso:
basename "$PWD"
O
IFS=/
var=($PWD)
echo ${var[-1]}
Riporta nello spazio il separatore di nome file interno (IFS).
IFS=
C'è uno spazio dopo l'IFS.
basename $(pwd)
o
echo "$(basename $(pwd))"
pwd
è suddiviso in stringhe ed espanso glob prima di essere passato a basename
.
basename "$(pwd)"
sebbene sia molto inefficiente rispetto a just basename "$PWD"
, il che è di per sé inefficiente rispetto all'utilizzo di un'espansione dei parametri invece di chiamare basename
affatto.
Per i fantini di ricerca là fuori come me:
find $PWD -maxdepth 0 -printf "%f\n"
$PWD
in "$PWD"
per gestire correttamente nomi di directory insoliti.
di solito lo uso negli script sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
puoi usarlo per automatizzare le cose ...
Anche sotto grep con regex funziona,
>pwd | grep -o "\w*-*$"
Usa solo:
pwd | xargs basename
o
basename "`pwd`"
xargs
formultion è inefficiente e buggy quando i nomi delle directory contengono ritorni a capo letterali o caratteri di citazione, e la seconda formulazione chiama il pwd
comando in una subshell, anziché recuperare lo stesso risultato tramite un'espansione variabile incorporata.
Se vuoi vedere solo la directory corrente nell'area del prompt di bash, puoi modificare il .bashrc
file in ~
. Passa \w
a \W
nella riga:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Esegui source ~/.bashrc
e visualizzerà solo il nome della directory nell'area del prompt.
Rif: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Preferisco fortemente usare gbasename
, che fa parte dei coreutils GNU.
basename
lì. In genere viene chiamato solo gbasename
su MacOS e altre piattaforme che altrimenti vengono fornite con un nome di base non GNU.
I seguenti comandi comporteranno la stampa della directory di lavoro corrente in uno script bash.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1
conterrà l'attuale directory di lavoro. (2) I pushd
e popd
non servono a nulla qui perché qualsiasi cosa all'interno di backtick viene eseguita in una subshell - quindi non può influenzare la directory della shell madre per cominciare. (3) L'uso "$(cd "$1"; pwd)"
sarebbe sia più leggibile che resiliente nei confronti dei nomi di directory con spazi bianchi.