Ich stelle fest, dass ich viel wiederhole:
mkdir longtitleproject
cd longtitleproject
Gibt es eine Möglichkeit, dies in einer Zeile zu tun, ohne den Verzeichnisnamen zu wiederholen? Ich bin auf Bash hier.
mkdir longtitleprojectdanncd !^
Ich stelle fest, dass ich viel wiederhole:
mkdir longtitleproject
cd longtitleproject
Gibt es eine Möglichkeit, dies in einer Zeile zu tun, ohne den Verzeichnisnamen zu wiederholen? Ich bin auf Bash hier.
mkdir longtitleprojectdanncd !^
Antworten:
Es gibt keinen eingebauten Befehl, aber Sie können leicht eine Funktion schreiben, die mkdirdann aufruft cd:
mkcd () {
mkdir "$1"
cd "$1"
}
Fügen Sie diesen Code in Ihre ~/.bashrcDatei ein (oder ~/.kshrcfür ksh-Benutzer oder ~/.zshrcfür zsh-Benutzer). Es definiert eine aufgerufene Funktion mkcd. "$1"wird beim Ausführen durch das Argument der Funktion ersetzt.
Diese einfache Version hat mehrere Mängel:
-pOption an mkdir. (Dies kann oder auch nicht wünschenswert sein, da es das Risiko eines Tippfehler unentdeckt bleiben erhöht, zum Beispiel mkcd mydierctory/newsubwird gerne erstellen mydierctoryund mydierctory/newsubwenn Sie gemeint erstellen newsubinnerhalb des bestehenden mydirectory.)-ist aber nicht nur -dann mkdirund cdwird es als Option interpretieren. Wenn es nur so ist -, cdwird es so interpretiert, dass es bedeutet $OLDPWD. Wenn es +von 0 oder mehr Ziffern gefolgt wird, cdwird es in zsh als Index im Verzeichnisstapel interpretiert. 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.mkdirfolgt nicht CDPATH, cdtut es aber. Wenn Sie also CDPATHeinen Wert festgelegt haben, der nicht beginnt .(eine zugegebenermaßen etwas ungewöhnliche Konfiguration), werden Sie cdmöglicherweise in ein anderes Verzeichnis als das gerade erstellte gebracht. Das Voranstellen ./auf relative Pfade behebt dieses Problem (es wird CDPATHignoriert).mkdirfehlschlägt, wird versucht, es auszuführen cd. Fix: Verwenden Sie &&diese Option, 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, cdin ein anderes Verzeichnis zu wechseln als das, das mkdirgerade in einem Randfall erstellt wurde: Wenn das Argument to einen symbolischen Link mkcdenthält ..und durchläuft. Wenn zum Beispiel das aktuelle Verzeichnis eine symbolische Verknüpfung zu ist /tmp/hereund mylinkist /somewhere/else, mkdir mylink/../foowird /somewhere/else/foowährenddessen eine cd mylink/../fooÄnderung in erstellt foo. Es reicht nicht aus, im Argument nach symbolischen Links zu suchen, da die Shell auch symbolische Links in ihrem eigenen aktuellen Verzeichnis verfolgt und daher cd /tmp/mylink; mkdir ../foo; cd ../foonicht in das neue Verzeichnis ( /somewhere/else/foo), sondern in wechselt /tmp/foo. Ein Fix für dieses cdProblem besteht darin, zuerst alle Pfadkomponenten auflösen zu lassen ..(es ist nicht sinnvoll, foo/..if zu verwendenfooexistiert nicht, muss also mkdirnie gesehen werden ..).
Wir kommen zu dieser 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 beim ersten cdAufruf eine Subshell ?)
Wenn mkdir fehlschlägt, möchte ich sicher sein, das aktuelle Verzeichnis nicht zu ändern. 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 updates OLDPWD aufrufen, möchten wir dies nur einmal tun (oder OLDPWD wiederherstellen).
Es gibt auch weniger spezialisierte Möglichkeiten, das Wort aus der vorherigen Zeile nicht erneut eingeben zu müssen:
cd dann Esc .(oder Alt+ .) ein, um das letzte Argument aus dem vorherigen Befehl einzufügen.cd !$Führt cddas letzte Argument des vorherigen Befehls aus.mkdirin cd.kshund funktioniert auch in dieser zshReihenfolge) für "das letzte Wort des vorherigen Befehls wiederholen". Ich benutze es ziemlich oft.
/a/b/..//würde eigentlich funktionieren aber nicht /a/b/../c. Fest. Ich habe die Frage einem breiteren Publikum gestellt.
mkcd() { mkdir -p "$1" && cd "$1"; }scheint in (meiner Instanz von) zsh kein Problem 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(Beinhaltet das Setup und) zeigt an /tmp/here/foo, was erstellt wurde (und was ich erwartet habe). bashfälschlicherweise erstellt und ändert /var/tmp/somewhere/foo.
Dies ist der Einzeiler, den Sie brauchen. Keine weitere Konfiguration erforderlich:
mkdir longtitleproject && cd $_
Die $_Variable in Bash ist das letzte Argument, das dem vorherigen Befehl übergeben wurde. In diesem Fall der Name des gerade erstellten Verzeichnisses. Wie erklärt 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 Sie cd $_das letzte Argument des vorherigen Befehls statt abzurufen , cd !$da cd !$gibt das letzte Argument des vorherigen Befehls in der Shell - Geschichte :
cd ~/
mkdir folder && cd !$
Sie landen zu Hause (oder ~ /)
cd ~/
mkdir newfolder && cd $_
Sie landen in Newfolder unter zu Hause! (oder ~ / newfolder)
mkdir foo && cd foo, was nicht praktisch ist.
Es wäre mir nie in den Sinn gekommen, dieses Verhalten zu skripten, da ich fast stündlich Folgendes eingebe ...
$ mkdir someDirectory<ENTER>
$ cd !$
wo bash freundlicherweise !$mit dem letzten Wort der letzten Zeile ersetzt; dh der lange Verzeichnisname, den Sie eingegeben haben.
Darüber hinaus ist die Dateinamenergänzung in solchen Situationen Ihr Freund. Wenn Ihr neues Verzeichnis die einzige Datei im Ordner ist, erhalten Sie durch ein schnelles Doppelklicken TABdas neue Verzeichnis, ohne es erneut einzugeben.
Obwohl es cool ist, dass Sie mit bash so häufige Aufgaben wie in den anderen Antworten beschrieben skripten können, ist es meiner Meinung nach besser, die Befehlszeilen-Bearbeitungsfunktionen von bash zu erlernen, damit Ihnen bei der Arbeit auf einem anderen Computer die Syntax nicht entgeht Zucker, den Ihre benutzerdefinierten Skripte bieten.
Wie pro Welche Anpassungen haben Sie auf Ihrem Shell - Profil getan Produktivität zu erhöhen? , so mache ich es:
# 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.
-pOption zu mkdir wird Fehler unterdrücken.
mcdBefehl? Welches Paket oder Projekt bietet diesen Befehl?
Wenn Sie Oh My Zsh verwenden, gibt es einen Befehl namens take , der genau dies ausführt . Es würde ungefähr so aussehen.
take myfolder
Das habe ich eigentlich zufällig gefunden. Ich habe gerade nachgesehen und es ist auf diesem Cheat aus dem Oh My Zsh GitHub Wiki aufgelistet. Es ist ein ziemlich nützlicher Befehl und anscheinend sehr einfach, sich selbst zu erstellen.
take:) Perfekt! Übrigens - iTerm2 mit Oh My Zsh. Hier gibt es tatsächlich 3 perfekte Antworten. Dieser, der von @ jesús-carrera, und die ausgewählte Antwort. Hängt von Ihrem Setup und Ihren Vorlieben ab.
Hier eine kleine Variante, die es zu erwähnen gilt:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
Fügen Sie dies zu Ihrem hinzu ~/.bash_profileund Sie können es dann mkdirwie gewohnt verwenden (sobald Sie es sourcegetan haben), außer jetzt wird die obige Funktion anstelle des Standardbefehls mkdirausgeführt.
Beachten Sie, dass hierdurch keine Eingaben gemäß der von Gilles akzeptierten Antwort validiert werden , sondern nur demonstriert wird, wie Sie Builtins (effektiv) überschreiben können.
Aus den Dokumenten (leicht umschrieben):
command mkdir [args]LäuftmkdirunterargsIgnorierung der genannten Shell-Funktionenmkdir. Es werden nur Shell-Befehle oder Befehle ausgeführt, die beim Durchsuchen des PFADS gefunden wurden. Wenn eine Shell-Funktion mit dem Namen vorhanden istls, führtcommand lsdie Ausführung innerhalb der Funktion den externen Befehl aus,lsanstatt die Funktion rekursiv aufzurufen
Ich glaube builtinerzielt ein ähnliches Ergebnis wie command.
$dir
commandals Alternative.
Ich habe ein Skript erstellt, das das Verzeichnis erstellt und dann die CDs darauf, dann habe ich ihm einen Alias gegeben. Und hier ist ein Kern, in dem ich es beschreibe.
https://gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-bedeutet-sein
Die obigen Antworten wurden einfach automatisiert und ein einmaliges ausführbares Skript erstellt:
fun='
mkcd ()
{
mkdir -p -- "$1" && cd -P -- "$1"
}'
echo "$fun" >> ~/.bashrc
Kopieren Sie dies einfach in eine neue Datei mkcd.shund führen Sie es nur einmal im Terminal durch bash mkcd.sh. Führen Sie dann aus source ~/.bashrc, damit es in der aktuellen Sitzung funktioniert.
Danach können Sie mit mkcd some_dirdas Verzeichnis erstellen und direkt eingeben.
~/.bashrcDatei anzuhängen (mit einer bereits gegebenen Antwort)? Und wie schlagen Sie vor, dieses mkcd.shSkript zu erstellen ? Vielleicht mit einem Redakteur? Das sieht nach mehr Arbeit als nur Bearbeitung aus ~/.bashrc. Welchen Vorteil hat dies gegenüber der akzeptierten Antwort? …………………………………………………………………………………………………………………………………………………………………….
mcdvon unix.stackexchange.com/questions/6628/…