Jag upplever att jag upprepar mycket av:
mkdir longtitleproject cd longtitleproject
Finns det ett sätt att göra det på en rad utan att upprepa katalognamnet? Jag är bash här.
Kommentarer
Svar
Detta är enfodret som du behöver. Ingen annan konfiguration behövs:
mkdir longtitleproject && cd $_
Variabeln $_
, är det sista argumentet för det föregående kommandot. I det här fallet är namnet på katalogen du just skapade. Som förklaras i 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.
Använd cd $_
för att hämta det senaste argumentet föregående kommando istället för cd !$
eftersom cd !$
ger det sista argumentet för föregående kommando i skalhistoriken :
cd ~/ mkdir folder && cd !$
du hamnar hemma (eller ~ /)
cd ~/ mkdir newfolder && cd $_
du hamnar i ny mapp under hemmet !! (eller ~ / nymapp)
Kommentarer
- Varför på jorden är det här inte det accepterade svaret
- @JSmyth Jag håller med , detta är en one-liner som använder inbyggd skalfunktionalitet
- Jag tror att OP försöker undvika att använda de två kommandona. Svaret är (nästan) lika giltigt som att göra
mkdir foo && cd foo
, vilket inte är ’ t praktiskt. - OP är frågar efter en one-liner som inte ’ t behöver upprepa katalognamnet, och detta är det
- Genom uppröstningarna är det ’ är uppenbart att många tycker att svaret är användbart. Jag ’ Jag anger varför jag inte ’ inte valde det här svaret: Jag ’ är väldigt mycket troligen skriver fel
&& cd $_
eftersom tangenterna är så långt borta från hemraden, så tekniskt korrekt är det ’ inte ergonomiskt. Jag uppskattar det faktum att det ’ inte är miljöberoende och det ’ är användbart att veta. Tack!
Svar
Det finns inget inbyggt kommando, men du kan enkelt skriva en funktion som ringer mkdir
sedan cd
:
mkcd () { mkdir "$1" cd "$1" }
Sätt den här koden i din ~/.bashrc
-fil (eller ~/.kshrc
för ksh-användare, eller ~/.zshrc
för zsh-användare). Den definierar en funktion som heter mkcd
. "$1"
kommer att ersättas med argumentet för funktionen när du kör den.
Den här enkla versionen har flera fel:
- Du kan inte skapa en kedja med underkataloger på en gång. Åtgärd: skicka
-p
tillmkdir
. (Detta kan eller inte kan vara önskvärt, eftersom det ökar risken för att ett skrivfel blir oupptäckt, t.ex.mkcd mydierctory/newsub
skapar gärnamydierctory
ochmydierctory/newsub
när du tänkte skapanewsub
inuti befintligtmydirectory
.) - Om argumentet börjar med
-
men inte ”t bara-
, så tolkarmkdir
ochcd
det som ett alternativ. Om det bara är-
, tolkarcd
det så att det betyder$OLDPWD
. det ”s+
följt av 0 eller fler siffror, då tolkarcd
i zsh det som ett index i katalogstacken. Du kan åtgärda det första problemet, men inte de andra två, genom att skicka--
före argumentet. Du kan åtgärda alla dessa problem genom att lägga till./
till argumentet om det är en relativ sökväg. -
mkdir
följer inteCDPATH
, mencd
gör det, så om du har ställt inCDPATH
till ett värde som inte börjar med.
(en visserligen något ovanlig konfiguration), då kancd
ta dig till en annan katalog än den som just skapades.Att förbereda./
till relativa sökvägar fixar detta¹ (det gör attCDPATH
ignoreras). - Om
mkdir
misslyckas, det försöker köracd
. Fix: använd&&
för att separera de två kommandona.
Fortfarande ganska enkelt:
mkcd () { case "$1" in /*) :;; *) set -- "./$1";; esac mkdir -p "$1" && cd "$1" }
Denna version har fortfarande potential att få cd
att gå in i en annan katalog än den att mkdir
precis skapats i ett kantfall: om argumentet till mkcd
innehåller ..
och går igenom en symbolisk länk. Till exempel, om den aktuella katalogen är /tmp/here
och mylink
är en symbolisk länk till /somewhere/else
, sedan skapar mkdir mylink/../foo
/somewhere/else/foo
medan cd mylink/../foo
ändras till foo
. Det är inte tillräckligt för att leta efter symboliska länkar i argumentet, eftersom skalet också spårar symboliska länkar i sin egen aktuella katalog, så cd /tmp/mylink; mkdir ../foo; cd ../foo
ändras inte till den nya katalogen (/somewhere/else/foo
) men till /tmp/foo
. En fix för detta är att låta cd
inbyggt lösa allt ..
sökvägskomponenter först (det är inte meningsfullt att använda foo/..
om foo
inte ” t existerar, så mkdir
behöver aldrig se någon ..
).
Vi kommer till den här robusta om det är något blodig 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 }
(Övning: varför använder jag en subshell för första gången cd
samtal?)
Om mkdir misslyckas vill jag vara säker på att inte ändra den aktuella katalogen. Att byta tillbaka med cd – eller $ OLDPWD är inte tillräckligt bra om skalet inte har det tillstånd att ändra till sin nuvarande katalog. Dessutom ringer cd-uppdateringar OLDPWD, så vi vill bara göra det en gång (eller återställa OLDPWD).
Det finns också mindre specialiserade sätt att inte behöva skriva ordet från föregående rad:
- Skriv
cd
och sedan Esc . (eller Alt + . ) för att infoga det sista argumentet från föregående kommando. -
cd !$
körcd
på det sista argumentet i föregående kommando. - Tryck Upp för att återkalla föregående kommandorad och redigera den sedan att ändra
mkdir
tillcd
.
¹ se upp dock att det fungerar inte i ksh93 eftersom u+
version , fixad i 93u + m / 1.0.0-alpha + d1483150 2021-01-05
Kommentarer
- Tack! Esc. verkar det mest praktiska för mig, gör nyckelsekvensen har någon speciell m vill?
- Det ’ är bara Bash (och ärvt från
ksh
, och fungerar också izsh
) sekvens för ” upprepa sista ordet i föregående kommando ”. Jag använder det ganska ofta. - @Gilles I ’ Jag börjar tro att ” Gilles ” konto delas faktiskt av en expertpanel. 😉
- @StephaneChazelas
/a/b/..//
fungerar faktiskt men inte/a/b/../c
. Fast. Jag ’ har ställt frågan till en bredare publik. -
mkcd() { mkdir -p "$1" && cd "$1"; }
verkar inte ’ t verkar vara ett problem i (min instans av) zsh.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
(inkluderar installationen och) visar/tmp/here/foo
vilket är vad som skapades (och vad jag förväntade mig).bash
felaktigt skapar och ändras till/var/tmp/somewhere/foo
.
Svar
Det skulle aldrig ha dykt upp för mig att skriva upp detta beteende eftersom jag anger följande på nära håll varje timme …
$ mkdir someDirectory<ENTER> $ cd !$
där bash vänligen ersätter !$
med det sista ordet i den sista raden; det vill säga det långa katalognamnet som du angav.
Dessutom är filnamnens komplettering din vän i sådana situationer. Om din nya katalog var den enda filen i mappen skulle en snabb dubbel TAB ge dig den nya katalogen utan att gå in i den igen.
Även om det är coolt att bash tillåter dig för att skriva ut sådana vanliga uppgifter som de andra svaren tyder på, tycker jag att det är bättre att lära sig de kommandoradsredigeringsfunktioner som bash har att erbjuda så att när du arbetar på en annan maskin saknar du det syntaktiska sockret som dina anpassade skript ger.
Kommentarer
- Finns det ett bra ställe att ta reda på om de viktigaste bash-quirks som den här?
- @ dominicbri7 Generellt kommer under ” redigering av bash-kommandoraden ” Googling samma ger följande som toppresultat web.mit.edu/gnu/doc/html/features_7.html Mer specifikt är! $ ett exempel på en Word Designator se gnu.org/software /bash/manual/bashref.html#Word-Designators
Svar
Om du använder Åh min Zsh, där ”ett kommando som heter ta som gör exakt detta. Det skulle se ut så här.
take myfolder
Jag hittade den här av misstag. Jag tittade bara och den listades på detta cheatsheat från wiki Oh My Zsh GitHub. Det är ett ganska användbart kommando och uppenbarligen väldigt enkelt att skapa själv.
Kommentarer
- Jag visste aldrig om
take
🙂 Perfekt! btw – iTerm2 med Oh My Zsh. Det finns faktiskt 3 perfekta svar här. Den här, den av @jes ú s-carrera, och det valda svaret. Beror på din inställning och preferens.
Svar
Enligt Vilka anpassningar har du gjort på din skalprofil för att öka produktiviteten? , så gör jag det:
# make a directory and cd to it mcd() { test -d "$1" || mkdir "$1" && cd "$1" }
det betyder att det också fungerar om katalogen redan finns.
Kommentarer
- Alternativet
-p
till mkdir kommer att undertrycka fel. - mcd är ett redan befintligt kommando. Även om du ’ precis har gett ett exempel använde jag det själv som det ’ en bokstav som är kortare än mkcd.
- @Dharmit Shah: Vad är det befintliga
mcd
kommandot? Vilket paket eller projekt ger det här kommandot? - mtools tillhandahåller mcd-kommandot. Dess mansida säger ” Kommandot mcd används för att ändra mtools arbetskatalog på MS-DOS-disken. ”
Svar
Eller så kan du bara skapa en kort variabel direkt och använda den två gånger x = longproject ; mkdir $x ; cd $x
– vilket jag erkänner är fortfarande längre än att använda en shellscript-funktion 🙂
Svar
Detta är en enkel sak att göra i ett bash-skript / -funktion. Jag skapade en väldigt läsbar och tillräckligt dokumenterad handledning inklusive skript som fungerar på både Linux och MacOS (detta kommer också att upprätthållas i framtiden).
Mitt mål för handledningskomplexiteten är: skriven för en målgrupp med de enda förutsättningarna är att användaren har en puls och kan läsa engelska, så ge feedback om du behöver hjälp.
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
För att installera detta har du två alternativ:
- Först är att lägga till funktionen i din
.bashrc
-fil. - Den andra är att lägga till filen i din sökväg och käll sedan in filen i din
.bash_profile
-fil.
Återigen är README-filen mycket detaljerad om hur du gör det.
Lycka till!
Svar
Här ”är en liten variant som är värt att nämna:
function mkdir() { local dir=$1 command mkdir "$dir" && cd "$dir" }
Lägg till detta i yo ur ~/.bash_profile
och du kan sedan använda mkdir
som vanligt (när du väl har source
” d it), förutom nu kommer den att köra funktionen ovan snarare än standardkommandot mkdir
.
Observera att detta inte validerar ingång enligt den accepterade svar av Gilles , men visar hur du (effektivt) kan åsidosätta inbyggda.
Från docs (omformulerar något):
command mkdir [args]
körmkdir
medargs
ignorerar alla skalfunktioner med namnetmkdir
. Endast shell-inbyggda kommandon eller kommandon som hittats genom att söka i PATH körs. Om det finns en skalfunktion med namnetls
körscommand ls
inom funktionen det externa kommandotls
istället för att anropa funktionen rekursivt
Jag tror att builtin
uppnår ett liknande resultat som command
.
Kommentarer
- du borde definitivt citera
$dir
- @Jeff, kom överens, men det accepterade svaret har all validering man skulle behöva.Jag ’ presenterar just användningen av
command
som ett alternativ.
Svara
Lägga till hjälpfunktion till BASH, ZSH eller KSH
Skapa mkcd
kommando till din miljö i en rad
echo -e "mkcd() {\n mkdir -p "$1" && cd $_\n}" >> ~/.${0//-/}rc && . ~/.${0//-/}rc
Svar
Om du använder Oh-my-zsh , take
-kommandot gör tricket. Ta en titt på fuskark .
Svar
Automatiserade bara ovanstående svar och gjorde ett körbart skript en gång:
fun=" mkcd () { mkdir -p -- "$1" && cd -P -- "$1" }" echo "$fun" >> ~/.bashrc
Kopiera bara detta i en ny fil mkcd.sh
och kör den bara en gång i terminalen med bash mkcd.sh
. Kör sedan source ~/.bashrc
för att få det att fungera under den aktuella sessionen.
Därefter kan du använda mkcd some_dir
för att skapa och ange direkt i den katalogen.
Kommentarer
- Du föreslår att du skriver ett skript (i en fil) vars enda syfte är att lägga till
~/.bashrc
fil (med ett svar som redan har givits)? Och hur föreslår du att du skapar dettamkcd.sh
skript? Med en redaktör, kanske? Det ser ut som mer arbete än bara att redigera~/.bashrc
. Vilken fördel har detta framför det accepterade svaret? …………………………………………………………………………… P.S. Detta kommer att misslyckas på grund av att citera problem, vilket säger att du inte ens har provat det själv. Det fungerar. Om du inte tror ’, prova det. Och om att inte försöka, använde jag hela dagen för att skriva sådana manus i bash och python idag. - Jag försökte det du skrev. Det fungerar inte .
mcd
från unix.stackexchange.com/questions/6628/…mkdir longtitleproject
och sedancd !^