it-swarm.com.de

Gibt es einen Einzeiler, mit dem ich ein Verzeichnis erstellen und gleichzeitig in dieses wechseln kann?

Ich wiederhole viel:

mkdir longtitleproject
cd longtitleproject

Gibt es eine Möglichkeit, dies in einer Zeile zu tun, ohne den Verzeichnisnamen zu wiederholen? Ich bin hier auf Bash.

166
methodofaction

Es gibt keinen eingebauten Befehl, aber Sie können einfach eine Funktion schreiben, die mkdir und dann cd aufruft:

mkcd () {
  mkdir "$1"
  cd "$1"
}

Fügen Sie diesen Code in Ihre ~/.bashrc - Datei ein (oder ~/.kshrc Für ksh-Benutzer oder ~/.zshrc Für zsh-Benutzer). Es definiert eine Funktion namens mkcd. "$1" Wird beim Ausführen durch das Argument der Funktion ersetzt.

Diese einfache Version weist mehrere Mängel auf:

  • Sie können nicht gleichzeitig eine Kette von Unterverzeichnissen erstellen. Fix: Übergeben Sie die Option -p An mkdir. (Dies kann wünschenswert sein oder auch nicht, da es das Risiko erhöht, dass ein Tippfehler unentdeckt bleibt. Beispielsweise erstellt mkcd mydierctory/newsub Glücklicherweise mydierctory und mydierctory/newsub, Wenn Sie newsub innerhalb des vorhandenen mydirectory erstellen möchten.)
  • Wenn das Argument mit - Beginnt, aber nicht nur - Ist, interpretieren mkdir und cd es als Option. Wenn es nur - Ist, interpretiert cd es als $OLDPWD. Wenn es + Gefolgt von 0 oder mehr Ziffern ist, interpretiert cd in zsh es als Index im Verzeichnisstapel. Sie können das erste Problem beheben, aber nicht die beiden anderen, indem Sie vor dem Argument -- Übergeben. Sie können all diese Probleme beheben, indem Sie dem Argument ./ Voranstellen, wenn es sich um einen relativen Pfad handelt.
  • mkdir folgt nicht CDPATH, cd jedoch. Wenn Sie also CDPATH auf einen Wert gesetzt haben, der nicht mit . beginnt (eine zugegebenermaßen etwas ungewöhnliche Konfiguration), führt cd Sie möglicherweise in ein anderes Verzeichnis als die, die gerade erstellt wurde. Das Voranstellen von ./ An relative Pfade behebt dies (es bewirkt, dass CDPATH ignoriert wird).
  • Wenn mkdir fehlschlägt, wird versucht, cd auszuführen. Fix: Verwenden Sie &&, Um die beiden Befehle zu trennen.

Immer noch ziemlich einfach:

mkcd () {
  case "$1" in /*) :;; *) set -- "./$1";; esac
  mkdir -p "$1" && cd "$1"
}

Diese Version hat immer noch das Potenzial, cd in ein anderes Verzeichnis zu verschieben als das, das mkdir gerade in einem Edge-Fall erstellt hat: Wenn das Argument zu mkcd.. Enthält und über einen symbolischen Link geht. Wenn das aktuelle Verzeichnis beispielsweise /tmp/here Ist und mylink eine symbolische Verknüpfung zu /somewhere/else Ist, erstellt mkdir mylink/../foo/somewhere/else/foo, Während sich cd mylink/../foo Ändert in foo. Es reicht nicht aus, im Argument nach symbolischen Links zu suchen, da die Shell auch symbolische Links in ihrem eigenen aktuellen Verzeichnis verfolgt, sodass cd /tmp/mylink; mkdir ../foo; cd ../foo Nicht in das neue Verzeichnis (/somewhere/else/foo) Wechselt, sondern in /tmp/foo. Eine Lösung hierfür besteht darin, dass der integrierte cd zuerst alle .. - Pfadkomponenten auflöst (es ist nicht sinnvoll, foo/.. Zu verwenden, wenn foo nicht vorhanden ist, sodass mkdir niemals angezeigt werden muss ..).

Wir kommen zu dieser robusten, wenn auch leicht blutigen Version:

mkcd () {
  case "$1" in
    */..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
    /*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
    /*) mkdir -p "$1" && cd "$1";;
    */../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
    ../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
    *) mkdir -p "./$1" && cd "./$1";;
  esac
}

(Übung: Warum verwende ich eine Subshell für den ersten Aufruf von cd?)

Wenn mkdir fehlschlägt, möchte ich sicherstellen, dass das aktuelle Verzeichnis nicht geändert wird. Das Zurückwechseln mit cd - oder $ OLDPWD ist nicht gut genug, wenn die Shell nicht berechtigt ist, in ihr aktuelles Verzeichnis zu wechseln. Wenn Sie cd aufrufen, wird OLDPWD aktualisiert, sodass wir dies nur einmal tun möchten (oder OLDPWD wiederherstellen möchten).


Es gibt auch weniger spezielle Möglichkeiten, das Wort aus der vorherigen Zeile nicht erneut eingeben zu müssen:

  • Geben Sie dann cd ein Esc. (oder Alt+.), um das letzte Argument aus dem vorherigen Befehl einzufügen.
  • cd !$ Führt cd für das letzte Argument des vorherigen Befehls aus.
  • Drücken Sie Up Um die vorherige Befehlszeile abzurufen, bearbeiten Sie sie, um mkdir in cd zu ändern.

Dies ist der Einzeiler, den Sie benötigen. Keine andere Konfiguration erforderlich:

mkdir longtitleproject && cd $_

Das $_ Variable in Bash ist das letzte Argument, das dem vorherigen Befehl gegeben wurde. In diesem Fall der Name des gerade erstellten Verzeichnisses. Wie in man bash:

_         At  Shell  startup,  set to the absolute pathname used to invoke
          the Shell or Shell script being executed as passed in the  envi‐
          ronment  or  argument  list.   Subsequently, expands to the last
          argument to the previous command, after expansion.  Also set  to
          the  full  pathname  used  to  invoke  each command executed and
          placed in the environment exported to that command.  When check‐
          ing  mail,  this  parameter holds the name of the mail file cur‐
          rently being checked."$_" is the last argument of the previous command.

Verwenden cd $_, um das letzte Argument des vorherigen Befehls anstelle von cd !$ weil cd !$ gibt das letzte Argument des vorherigen Befehls an in der Shell-Historie:

cd ~/
mkdir folder && cd !$

du landest zu Hause (oder ~ /)

cd ~/
mkdir newfolder && cd $_

sie landen in einem neuen Ordner unter zu Hause! (oder ~/neuer Ordner)

151
Jesús Carrera

Es wäre mir nie in den Sinn gekommen, dieses Verhalten zu skripten, da ich fast stündlich Folgendes eingebe ...

$ mkdir someDirectory<ENTER>
$ cd !$

wobei bash freundlicherweise !$ durch das letzte Wort der letzten Zeile ersetzt; d.h. der lange Verzeichnisname, den Sie eingegeben haben.

Darüber hinaus ist die Vervollständigung des Dateinamens in solchen Situationen Ihr Freund. Wenn Ihr neues Verzeichnis die einzige Datei im Ordner war, verdoppeln Sie diese schnell TAB würde Ihnen das neue Verzeichnis geben, ohne es erneut einzugeben.

Obwohl es cool ist, mit bash solche allgemeinen Aufgaben zu skripten, wie die anderen Antworten vermuten lassen, ist es meiner Meinung nach besser, die Befehlszeilenbearbeitungsfunktionen von bash zu erlernen, damit Ihnen bei der Arbeit an einem anderen Computer die Syntaktik nicht fehlt Zucker, den Ihre benutzerdefinierten Skripte bereitstellen.

30
Rob

Gemäß Welche Anpassungen haben Sie an Ihrem Shell-Profil vorgenommen, um die Produktivität zu steigern? , so mache ich das:

# make a directory and cd to it
mcd()
{
    test -d "$1" || mkdir "$1" && cd "$1"
}

dies bedeutet, dass es auch funktioniert, wenn das Verzeichnis bereits vorhanden ist.

17
Mikel

Wenn Sie Oh My Zsh verwenden, gibt es einen Befehl namens take , der genau dies tut. Es würde ungefähr so ​​aussehen.

take myfolder

Ich habe diesen tatsächlich zufällig gefunden. Ich habe gerade nachgesehen und es ist auf dieser Cheatsheat aus dem Oh My Zsh GitHub-Wiki aufgeführt. Es ist ein ziemlich nützlicher Befehl und anscheinend sehr einfach, sich selbst zu erstellen.

16
Jordan Harris

Oder Sie können einfach eine kurze Variable im laufenden Betrieb erstellen und zweimal verwenden x = longproject ; mkdir $x ; cd $x - was ich zugeben muss ist immer noch länger als die Verwendung einer Shellscript-Funktion :)

3
sakisk

Ich habe ein Skript erstellt, das das Verzeichnis und dann die CDs dazu erstellt, dann habe ich ihm einen Alias ​​gegeben. Und hier ist ein Kern, wo ich es beschreibe.

https://Gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be

0
Marcus Rehn

Hier ist eine kleine Variante, die es wert ist, erwähnt zu werden:

function mkdir() {
    local dir=$1
    command mkdir "$dir"  &&  cd "$dir"
}

Fügen Sie dies Ihrem ~/.bash_profile und Sie können dann mkdir wie gewohnt verwenden (sobald Sie source 'd es getan haben), außer jetzt wird die obige Funktion anstelle des Standardbefehls mkdir ausgeführt .

Beachten Sie, dass dies die Eingabe nicht gemäß dem akzeptierten Antwort von Gilles validiert, sondern zeigt, wie Sie eingebaute Elemente (effektiv) überschreiben können.

Aus den Dokumenten (leicht umschrieben):

command mkdir [args] führt mkdir aus, wobei args alle Shell-Funktionen mit dem Namen mkdir ignoriert. Es werden nur Shell-integrierte Befehle oder Befehle ausgeführt, die beim Durchsuchen des Pfads gefunden wurden. Wenn es eine Shell-Funktion mit dem Namen ls gibt, wird command ls innerhalb der Funktion führt den externen Befehl ls aus, anstatt die Funktion rekursiv aufzurufen

Ich glaube, dass builtin ein ähnliches Ergebnis erzielt wie command.

0
Arj

Hinzufügen einer Hilfsfunktion zu BASH, ZSH oder KSH

Erstellen Sie in einer Zeile den Befehl mkcd für Ihre Umgebung

echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
0
Proximo