Finns det en one-liner som tillåter mig att skapa en katalog och flytta in i den samtidigt?

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 till mkdir. (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ärna mydierctory och mydierctory/newsub när du tänkte skapa newsub inuti befintligt mydirectory.)
  • Om argumentet börjar med - men inte ”t bara -, så tolkar mkdir och cd det som ett alternativ. Om det bara är -, tolkar cd det så att det betyder $OLDPWD. det ”s + följt av 0 eller fler siffror, då tolkar cd 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 inte CDPATH, men cd gör det, så om du har ställt in CDPATH till ett värde som inte börjar med . (en visserligen något ovanlig konfiguration), då kan cd ta dig till en annan katalog än den som just skapades.Att förbereda ./ till relativa sökvägar fixar detta¹ (det gör att CDPATH ignoreras).
  • Om mkdir misslyckas, det försöker köra cd. 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ör cd 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 till cd.

¹ 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å i zsh) 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

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ör mkdir med args ignorerar alla skalfunktioner med namnet mkdir. Endast shell-inbyggda kommandon eller kommandon som hittats genom att söka i PATH körs. Om det finns en skalfunktion med namnet ls körs command ls inom funktionen det externa kommandot ls 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 detta mkcd.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 .

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *