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 longtitleproject
danncd !^
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 longtitleproject
danncd !^
Antworten:
Es gibt keinen eingebauten Befehl, aber Sie können leicht eine Funktion schreiben, die mkdir
dann aufruft cd
:
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 aufgerufene Funktion mkcd
. "$1"
wird beim Ausführen durch das Argument der Funktion ersetzt.
Diese einfache Version hat mehrere Mängel:
-p
Option an mkdir
. (Dies kann oder auch nicht wünschenswert sein, da es das Risiko eines Tippfehler unentdeckt bleiben erhöht, zum Beispiel mkcd mydierctory/newsub
wird gerne erstellen mydierctory
und mydierctory/newsub
wenn Sie gemeint erstellen newsub
innerhalb des bestehenden mydirectory
.)-
ist aber nicht nur -
dann mkdir
und cd
wird es als Option interpretieren. Wenn es nur so ist -
, cd
wird es so interpretiert, dass es bedeutet $OLDPWD
. Wenn es +
von 0 oder mehr Ziffern gefolgt wird, cd
wird 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.mkdir
folgt nicht CDPATH
, cd
tut es aber. Wenn Sie also CDPATH
einen Wert festgelegt haben, der nicht beginnt .
(eine zugegebenermaßen etwas ungewöhnliche Konfiguration), werden Sie cd
möglicherweise in ein anderes Verzeichnis als das gerade erstellte gebracht. Das Voranstellen ./
auf relative Pfade behebt dieses Problem (es wird CDPATH
ignoriert).mkdir
fehlschlä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, cd
in ein anderes Verzeichnis zu wechseln als das, das mkdir
gerade in einem Randfall erstellt wurde: Wenn das Argument to einen symbolischen Link mkcd
enthält ..
und durchläuft. Wenn zum Beispiel das aktuelle Verzeichnis eine symbolische Verknüpfung zu ist /tmp/here
und mylink
ist /somewhere/else
, mkdir mylink/../foo
wird /somewhere/else/foo
wä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 ../foo
nicht in das neue Verzeichnis ( /somewhere/else/foo
), sondern in wechselt /tmp/foo
. Ein Fix für dieses cd
Problem besteht darin, zuerst alle Pfadkomponenten auflösen zu lassen ..
(es ist nicht sinnvoll, foo/..
if zu verwendenfoo
existiert nicht, muss also mkdir
nie 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 cd
Aufruf 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 cd
das letzte Argument des vorherigen Befehls aus.mkdir
in cd
.ksh
und funktioniert auch in dieser zsh
Reihenfolge) 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). bash
fä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.
-p
Option zu mkdir wird Fehler unterdrücken.
mcd
Befehl? 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_profile
und Sie können es dann mkdir
wie gewohnt verwenden (sobald Sie es source
getan haben), außer jetzt wird die obige Funktion anstelle des Standardbefehls mkdir
ausgefü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äuftmkdir
unterargs
Ignorierung 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 ls
die Ausführung innerhalb der Funktion den externen Befehl aus,ls
anstatt die Funktion rekursiv aufzurufen
Ich glaube builtin
erzielt ein ähnliches Ergebnis wie command
.
$dir
command
als 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.sh
und 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_dir
das Verzeichnis erstellen und direkt eingeben.
~/.bashrc
Datei anzuhängen (mit einer bereits gegebenen Antwort)? Und wie schlagen Sie vor, dieses mkcd.sh
Skript 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? …………………………………………………………………………………………………………………………………………………………………….
mcd
von unix.stackexchange.com/questions/6628/…