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

Ich wiederhole oft Folgendes:

 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.

Kommentare

Antwort

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

mkdir longtitleproject && cd $_ 

Die Variable $_ in bash, ist das letzte Argument für den vorherigen Befehl. In diesem Fall der Name des gerade erstellten Verzeichnisses. Wie unter man bash erläutert:

_ 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 Sie cd $_, um das letzte Argument abzurufen des vorherigen Befehls anstelle von cd !$, da cd !$ das letzte Argument des vorherigen Befehls In der Shell-Historie :

cd ~/ mkdir folder && cd !$ 

landen Sie zu Hause (oder ~ /)

cd ~/ mkdir newfolder && cd $_ 

Sie landen in einem neuen Ordner unter Ihrem Zuhause !! (oder ~ / newfolder)

Kommentare

  • Warum um alles in der Welt ist dies nicht die akzeptierte Antwort
  • @JSmyth Ich stimme zu Dies ist ein Einzeiler, der native Shell-Funktionen verwendet.
  • Ich denke, das OP versucht, die Verwendung der beiden Befehle zu vermeiden. Diese Antwort ist (fast) genauso gültig wie mkdir foo && cd foo, was ‚ nicht praktisch ist.
  • Das OP ist Fragen nach einem Einzeiler, der nicht ‚ den Verzeichnisnamen wiederholen muss, und das ist es
  • Nach den Upvotes ‚ Es ist offensichtlich, dass viele Leute diese Antwort nützlich finden. Ich ‚ werde angeben, warum ich ‚ diese Antwort nicht ausgewählt habe: Ich ‚ bin sehr Es ist wahrscheinlich, dass && cd $_ falsch eingegeben wird, da die Tasten so weit von der Ausgangszeile entfernt sind. Obwohl dies technisch korrekt ist, ist ‚ nicht ergonomisch. Ich schätze die Tatsache, dass ‚ nicht von der Umgebung abhängig ist und es ‚ nützlich ist, dies zu wissen. Danke!

Antwort

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

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

Geben Sie diesen Code ein Ihre ~/.bashrc -Datei (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 keine Kette von Unterverzeichnissen gleichzeitig erstellen. Korrektur: Übergeben Sie die Option -p an mkdir. (Dies kann wünschenswert oder nicht wünschenswert sein, da es das Risiko erhöht, dass ein Tippfehler unentdeckt bleibt, z. B. mkcd mydierctory/newsub erstellt gerne mydierctory und mydierctory/newsub, wenn Sie newsub innerhalb der vorhanden mydirectory.)
  • Wenn das Argument mit - beginnt, aber nicht nur -, dann mkdir und cd interpretieren es als Option. Wenn es nur - ist, interpretiert cd es als $OLDPWD es ist „s + gefolgt von 0 oder mehr Ziffern, dann 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 CDPATH gesetzt haben auf einen Wert, der nicht mit . beginnt (eine zugegebenermaßen etwas ungewöhnliche Konfiguration), dann bringt cd Sie möglicherweise in ein anderes Verzeichnis als derjenige, der gerade erstellt wurde.Das Voranstellen von ./ an relative Pfade behebt dieses Problem¹ (CDPATH wird ignoriert).
  • Wenn mkdir schlägt fehl und 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 als das andere zu verschieben dass mkdir gerade in einem Randfall erstellt wurde: Wenn das Argument für mkcd .. und enthält geht durch eine symbolische Verbindung. Wenn das aktuelle Verzeichnis beispielsweise /tmp/here lautet und mylink eine symbolische Verknüpfung zu /somewhere/else ist Dann erstellt mkdir mylink/../foo /somewhere/else/foo, während cd mylink/../foo 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), aber in /tmp/foo. Eine Lösung hierfür besteht darin, dass die eingebaute cd alle .. Pfadkomponenten zuerst (es ist nicht sinnvoll, foo/.. zu verwenden, wenn foo dies nicht tut “ t existiert, also muss mkdir niemals ..) sehen.

Wir kommen zu diesem robusten, wenn auch etwas 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 für die erste eine Subshell? cd Aufruf?)

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 dies nicht tut Berechtigung zum Wechseln in das aktuelle Verzeichnis. Wenn Sie cd aufrufen, wird OLDPWD aktualisiert, sodass wir es nur einmal ausführen (oder OLDPWD wiederherstellen) möchten.


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

  • Geben Sie cd und dann Esc ein. (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 Nach oben , um die vorherige Befehlszeile abzurufen, und bearbeiten Sie sie dann mkdir in cd ändern.

¹ Beachten Sie jedoch, dass funktioniert nicht in ksh93, da die u+ -Version in 93u + m / 1.0.0-alpha behoben ist + d1483150 2021-01-05

Kommentare

  • Danke! Die Esc. scheint mir am bequemsten zu sein, macht die Tastenfolge habe keine besonderen m eaning?
  • Es ‚ ist nur der Bash (und von ksh geerbt und funktioniert auch in zsh) Sequenz für “ Wiederhole das letzte Wort des vorherigen Befehls „. Ich benutze es ziemlich oft.
  • @ Gilles Ich ‚ beginne zu denken, dass die “ Gilles “ Konto wird tatsächlich von einer Expertengruppe geteilt. 😉
  • @StephaneChazelas /a/b/..// würde tatsächlich funktionieren, aber nicht /a/b/../c. Fest. Ich ‚ habe die Frage einem breiteren Publikum gestellt.
  • mkcd() { mkdir -p "$1" && cd "$1"; } scheint ‚ kein Problem in (meiner Instanz von) zsh zu sein. mkdir -p /var/tmp/somewhere/else /tmp/here; cd /tmp/here; ln -s /var/tmp/somewhere/else mylink; mkdir -p mylink/../foo && cd mylink/../foo; pwd (einschließlich Setup und) zeigt /tmp/here/foo an, was erstellt wurde (und was ich erwartet habe). bash erstellt und ändert fälschlicherweise /var/tmp/somewhere/foo.

Antwort

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.

Außerdem ist die Vervollständigung des Dateinamens in solchen Situationen Ihr Freund. Wenn Ihr neues Verzeichnis die einzige Datei im Ordner wäre, würde Ihnen ein schnelles doppeltes TAB das neue Verzeichnis geben, ohne es erneut einzugeben.

Obwohl es cool ist, erlaubt Ihnen diese Bash Um 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 auf einem anderen Computer der syntaktische Zucker, den Ihre benutzerdefinierten Skripte bieten, nicht entgeht.

Kommentare

Antwort

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

take myfolder 

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

Kommentare

  • Ich wusste nie über 🙂 Perfekt! Übrigens – iTerm2 mit Oh My Zsh. Hier gibt es tatsächlich 3 perfekte Antworten. Diese, die von @jes ú s-carrera, und Die ausgewählte Antwort hängt von Ihrer Einrichtung und Ihren Vorlieben ab.

Antwort

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.

Kommentare

  • Die Option -p für mkdir unterdrückt Fehler.
  • mcd ist ein bereits vorhandener Befehl. Obwohl Sie ‚ gerade ein Beispiel angegeben haben, habe ich es selbst als Ein Brief, der kürzer als mkcd ist.
  • @Dharmit Shah: Was ist der vorhandene Befehl mcd? Welches Paket oder Projekt stellt diesen Befehl bereit?
  • mtools stellt den Befehl mcd bereit. Auf der Manpage steht “ Mit dem Befehl mcd wird das Arbeitsverzeichnis mtools auf der MS-DOS-Festplatte geändert. “

Antwort

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 🙂

Antwort

Dies ist eine einfache Sache in einem Bash-Skript / Funktion zu tun. Ich habe ein sehr lesbares und ausreichend dokumentiertes Tutorial erstellt, das Skripte enthält, die sowohl unter Linux als auch unter MacOS funktionieren (dies wird auch in Zukunft beibehalten).

Mein Ziel für die Komplexität des Tutorials ist: geschrieben für eine Zielgruppe mit Die einzige Voraussetzung ist, dass der Benutzer einen Puls hat und Englisch lesen kann. Geben Sie daher bitte Feedback, wenn Sie Hilfe benötigen.

https://github.com/craigopie/shellscripts

 mcdir() { if [ $# -eq 0 ] || [ $1 = "-h" ] || [ $1 = "--help" ] then echo "Usage: [option...] {directory}" echo " -p, --path Create all directories in path " echo " -h, --help Shows this helpful information " echo return 0 fi ## create directory with a path if [ $1 = "-p" ] || [ $1 = "--path" ] then mkdir -p "$2" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$2" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 fi ## create directory in this location mkdir "$1" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$1" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 } export -f mcdir  

Um dies zu installieren, haben Sie zwei Optionen:

  • Zuerst fügen Sie die Funktion Ihrer .bashrc -Datei hinzu.
  • Die zweite besteht darin, die Datei Ihrem Pfad hinzuzufügen und geben Sie dann die Datei in Ihre .bash_profile -Datei ein.

Auch hier ist die README-Datei sehr detailliert.

Viel Glück!

Antwort

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 zu yo hinzu ur ~/.bash_profile und Sie können dann mkdir wie gewohnt verwenden (sobald Sie „source“ d it), außer jetzt wird die obige Funktion anstelle des Standardbefehls mkdir ausgeführt.

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

Aus dem docs (leicht umschrieben):

command mkdir [args] läuft mkdir wobei args jede Shell-Funktion 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, führt das Ausführen von command ls innerhalb der Funktion den externen Befehl ls anstatt die Funktion rekursiv aufzurufen

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

Kommentare

  • Sie sollten auf jeden Fall $dir
  • @Jeff, stimmte zu, aber die akzeptierte Antwort hat alle Validierungen, die man benötigen würde.Ich ‚ präsentiere nur die Verwendung von command als Alternative.

Antwort

Hinzufügen einer Hilfsfunktion zu BASH, ZSH oder KSH

Erstellen Sie einen mkcd -Befehl für Ihre Umgebung in eine Zeile

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

Antwort

Wenn Sie Oh-my-zsh verwenden Der Befehl take erledigt den Trick. Schauen Sie sich das Spickzettel an.

Antwort

Automatisieren Sie einfach die obigen Antworten und erstellen Sie ein einmalig ausführbares Skript:

fun=" mkcd () { mkdir -p -- "$1" && cd -P -- "$1" }" echo "$fun" >> ~/.bashrc 

Kopieren Sie dies einfach in eine neue Datei mkcd.sh und führen Sie es nur einmal im Terminal mit bash mkcd.sh aus. Führen Sie dann source ~/.bashrc aus, damit es in der aktuellen Sitzung funktioniert.

Danach können Sie mkcd some_dir zum Erstellen verwenden und geben Sie direkt in dieses Verzeichnis ein.

Kommentare

  • Sie schlagen vor, ein Skript (in einer Datei) zu schreiben, dessen einziger Zweck darin besteht, an das ~/.bashrc Datei (mit einer Antwort, die bereits gegeben wurde)? Und wie schlagen Sie vor, dieses mkcd.sh -Skript zu erstellen? Vielleicht mit einem Redakteur? Dies scheint mehr Arbeit zu sein als nur das Bearbeiten von ~/.bashrc. Welchen Vorteil hat dies gegenüber der akzeptierten Antwort? ………………………………………………………………………………………………………………………………………………………………………………………………………… Dies wird aufgrund von Zitierproblemen fehlschlagen, was mir sagt, dass Sie es noch nicht einmal selbst versucht haben.
  • Es tut mir leid, das zu sagen, aber ja, wie ich in meiner Antwort geschrieben habe, habe ich die obigen Antworten verwendet. Es funktioniert. Wenn Sie ‚ mir nicht glauben, versuchen Sie es. Und weil ich es nicht versucht habe, habe ich heute meinen ganzen Tag genutzt, um solche Skripte in Bash und Python zu schreiben.
  • Ich habe versucht, was Sie geschrieben haben. Es funktioniert nicht .

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.