Wie würde ich nur den aktuellen Arbeitsverzeichnisnamen in einem Bash-Skript oder noch besser nur einen Terminalbefehl erhalten?
pwdgibt den vollständigen Pfad des aktuellen Arbeitsverzeichnisses an, zB /opt/local/binaber ich will nurbin
Wie würde ich nur den aktuellen Arbeitsverzeichnisnamen in einem Bash-Skript oder noch besser nur einen Terminalbefehl erhalten?
pwdgibt den vollständigen Pfad des aktuellen Arbeitsverzeichnisses an, zB /opt/local/binaber ich will nurbin
Antworten:
Keine Notwendigkeit für einen Basisnamen und insbesondere keine Notwendigkeit für eine Unterschale, auf der pwd ausgeführt wird (was eine zusätzliche und teure Gabeloperation hinzufügt ); Die Shell kann dies intern mithilfe der Parametererweiterung tun :
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.
Beachten Sie, dass Sie, wenn Sie diese Technik unter anderen Umständen anwenden (nicht PWD, sondern bei einer anderen Variablen, die einen Verzeichnisnamen enthält), möglicherweise nachfolgende Schrägstriche kürzen müssen. Im Folgenden wird die Extglob-Unterstützung von bash verwendet , um auch mit mehreren nachgestellten Schrägstrichen zu arbeiten:
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"
Alternativ ohne extglob:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWDist der Name einer integrierten Bash-Variablen. Alle integrierten Variablennamen sind in Großbuchstaben angegeben (um sie von lokalen Variablen zu unterscheiden, die immer mindestens ein Kleinbuchstaben haben sollten). result=${PWD#*/}tut nicht bewerten zu /full/path/to/directory; Stattdessen wird nur das erste Element entfernt, wodurch es erstellt wird path/to/directory. Wenn Sie zwei #Zeichen verwenden, wird das Muster gierig und es werden so viele Zeichen wie möglich angezeigt. Weitere Informationen finden Sie auf der Seite zur Parametererweiterung, die in der Antwort verlinkt ist.
pwdnicht immer mit dem Wert von übereinstimmt , ob für bash die Option festgelegt ist usw. Dies war früher besonders unangenehm bei der Handhabung von Verzeichnissen mit automatischer Bereitstellung, bei denen das Aufzeichnen des physischen Pfads anstelle des logischen Pfads einen Pfad ergab, der es dem automatischen Zähler bei Verwendung ermöglichte, das verwendete Verzeichnis spontan zu entfernen. $PWDcd-o physical
shund cshund wenn Sie die Rücktaste wollten Sie das Ganze lesen arbeiten musste sttyman - Seite, und wir hatten eine positive Erfahrung!“
Verwenden Sie das basenameProgramm. Für Ihren Fall:
% basename "$PWD"
bin
basenameProgramms? Was ist falsch an dieser Antwort, außer dass die Anführungszeichen fehlen?
basenameist in der Tat ein externes Programm , das das Richtige tut, sondern läuft jede für eine Sache bash kann externes Programm tun out-of-the-Box mit nur integrierte Funktionalität albern ist, Auswirkungen auf die Leistung entstehen ( fork(), execve(), wait(), usw.) für kein Grund.
basenamehier nicht gelten dirname, da dirnamehat Funktionen , die ${PWD##*/}nicht der Fall ist - eine Zeichenkette ohne Schrägstriche zu verwandeln ., zum Beispiel. Während die Verwendung dirnameals externes Tool einen Leistungsaufwand verursacht, verfügt es auch über Funktionen, die dazu beitragen, diese auszugleichen.
functionSchlüsselwort ist POSIX-inkompatibel, ohne einen Wert gegenüber der standardisierten Syntax hinzuzufügen, und das Fehlen von Anführungszeichen würde Fehler in Verzeichnisnamen mit Leerzeichen verursachen. wdexec() { "./$(basename "$PWD")"; }könnte eine bevorzugte Alternative sein.
basenameweniger "effizient". Aber es ist wahrscheinlich mehr effizienter in Bezug auf die Produktivität der Entwickler , weil es einfach ist , im Vergleich zu erinnern an die hässliche bash Syntax. Also, wenn Sie sich daran erinnern, machen Sie es. Ansonsten basenamefunktioniert es genauso gut. Hat jemand jemals die "Leistung" eines Bash-Skripts verbessern und effizienter machen müssen?
$ echo "${PWD##*/}"
.
echo "${PWD##*/}".
name=${PWD##*/}wäre dies richtig und name=$(echo "${PWD##*/}")falsch (im Sinne einer unnötigen Ineffizienz).
Sie können eine Kombination aus pwd und basename verwenden. Z.B
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Ich mag die ausgewählte Antwort (Charles Duffy), aber seien Sie vorsichtig, wenn Sie sich in einem verknüpften Verzeichnis befinden und den Namen des Zielverzeichnisses möchten. Leider glaube ich nicht, dass dies in einem einzelnen Parametererweiterungsausdruck möglich ist, vielleicht irre ich mich. Das sollte funktionieren:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Um dies zu sehen, ein Experiment:
cd foo
ln -s . bar
echo ${PWD##*/}
meldet "bar"
So zeigen Sie die führenden Verzeichnisse eines Pfads an (ohne dass ein Fork-Exec von / usr / bin / dirname erforderlich ist):
echo ${target_PWD%/*}
Dies wird zB foo / bar / baz -> foo / bar transformieren
readlink -fhandelt es sich um eine GNU-Erweiterung, die auf den BSDs (einschließlich OS X) nicht verfügbar ist.
echo "$PWD" | sed 's!.*/!!'
Wenn Sie die Bourne-Shell verwenden oder ${PWD##*/}nicht verfügbar sind.
${PWD##*/}ist POSIX sh - jedes moderne / bin / sh (einschließlich Armaturenbrett, Asche usw.) unterstützt es; Um Bourne auf einer aktuellen Box zu treffen, müssen Sie sich auf einem leicht veralteten Solaris-System befinden. Darüber hinaus - echo "$PWD"; Das Weglassen der Anführungszeichen führt zu Fehlern (wenn der Verzeichnisname Leerzeichen, Platzhalterzeichen usw. enthält).
Überraschenderweise erwähnte niemand diese Alternative, die nur eingebaute Bash-Befehle verwendet:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Als zusätzlichen Bonus können Sie den Namen des übergeordneten Verzeichnisses leicht erhalten mit:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Diese funktionieren unter Bash 4.3-alpha oder neuer.
Verwenden:
basename "$PWD"
ODER
IFS=/
var=($PWD)
echo ${var[-1]}
Schalten Sie den internen Dateinamen-Separator (IFS) wieder auf Leerzeichen.
IFS=
Nach dem IFS steht ein Leerzeichen.
basename $(pwd)
oder
echo "$(basename $(pwd))"
pwderforderlich. Die Ausgabe von wird vor der Übergabe an Zeichenfolgen aufgeteilt und global erweitert basename.
basename "$(pwd)"- obwohl das im Vergleich zu just sehr ineffizient ist basename "$PWD", was selbst ineffizient ist im Vergleich zur Verwendung einer Parametererweiterung, anstatt überhaupt aufzurufen basename.
Für die Findjockeys da draußen wie mich:
find $PWD -maxdepth 0 -printf "%f\n"
$PWDin "$PWD", um ungewöhnliche Verzeichnisnamen korrekt zu behandeln.
Ich benutze dies normalerweise in sh-Skripten
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
Sie können dies verwenden, um Dinge zu automatisieren ...
Unten funktioniert grep with regex auch,
>pwd | grep -o "\w*-*$"
Benutz einfach:
pwd | xargs basename
oder
basename "`pwd`"
xargsFormulierung ist ineffizient und fehlerhaft, wenn Verzeichnisnamen wörtliche Zeilenumbrüche oder Anführungszeichen enthalten, und die zweite Formulierung ruft den pwdBefehl auf in einer Unterschale, anstatt dasselbe Ergebnis über eine integrierte variable Erweiterung abzurufen.
Wenn Sie nur das aktuelle Verzeichnis in der Bash-Eingabeaufforderungsregion anzeigen möchten, können Sie die .bashrcDatei in bearbeiten ~. Ändern Sie \wzu \Win der Zeile:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Ausführen source ~/.bashrcund es wird nur der Verzeichnisname in der Eingabeaufforderungsregion angezeigt.
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Ich bevorzuge stark die Verwendung gbasename, die Teil von GNU Coreutils ist.
basenamedort. Es wird normalerweise nur gbasenameunter MacOS und anderen Plattformen aufgerufen , die ansonsten mit einem Nicht-GNU-Basisnamen geliefert werden.
Die folgenden Befehle führen dazu, dass Ihr aktuelles Arbeitsverzeichnis in einem Bash-Skript gedruckt wird.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1das aktuelle Arbeitsverzeichnis enthält. (2) Das pushdund hat popdhier keinen Zweck, da alles in Backticks in einer Subshell ausgeführt wird - es kann also zunächst keinen Einfluss auf das Verzeichnis der übergeordneten Shell haben. (3) Die Verwendung "$(cd "$1"; pwd)"wäre sowohl lesbar als auch widerstandsfähiger gegenüber Verzeichnisnamen mit Leerzeichen.