Ik merk dat ik veel herhaal:
mkdir longtitleproject cd longtitleproject
Is er een manier om het op één regel te doen zonder de directorynaam te herhalen? Ik ben hier op bash.
Reacties
Antwoord
Dit is de one-liner die je nodig hebt. Geen andere configuratie nodig:
mkdir longtitleproject && cd $_
De $_
variabele, in bash, is het laatste argument dat aan het vorige commando is gegeven. In dit geval de naam van de map die je zojuist hebt gemaakt. Zoals uitgelegd 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.
Gebruik cd $_
om de laatste argu op te halen ment van het vorige commando in plaats van cd !$
omdat cd !$
het laatste argument van het vorige commando geeft in de shell-geschiedenis :
cd ~/ mkdir folder && cd !$
je eindigt thuis (of ~ /)
cd ~/ mkdir newfolder && cd $_
je komt terecht in de nieuwe map onder home !! (of ~ / newfolder)
Reacties
- Waarom is dit in vredesnaam niet het geaccepteerde antwoord
- @JSmyth Ik ga akkoord , dit is een oneliner die native shell-functionaliteit gebruikt.
- Ik denk dat het OP probeert de twee commandos te vermijden. Dit antwoord is (bijna) net zo geldig als
mkdir foo && cd foo
, wat niet ‘ handig is. - Het OP is vragen om een one-liner die ‘ t niet vereist om de directorynaam te herhalen, en dit is het
- Volgens de upvotes is het ‘ het is duidelijk dat veel mensen dit antwoord nuttig vinden. Ik ‘ zal aangeven waarom ik ‘ dit antwoord niet heb geselecteerd: ik ‘ ben erg zal waarschijnlijk
&& cd $_
verkeerd typen omdat de toetsen zo ver weg zijn van de startrij, dus hoewel technisch correct, is het ‘ niet ergonomisch. Ik waardeer het feit dat het ‘ niet afhankelijk is van de omgeving en dat het ‘ nuttig is om te weten. Bedankt!
Answer
Er is geen ingebouwd commando, maar je kunt gemakkelijk een functie schrijven die roept mkdir
aan en vervolgens cd
:
mkcd () { mkdir "$1" cd "$1" }
Zet deze code in uw ~/.bashrc
-bestand (of ~/.kshrc
voor ksh-gebruikers, of ~/.zshrc
voor zsh-gebruikers). Het definieert een functie genaamd mkcd
. "$1"
zal worden vervangen door het argument van de functie wanneer je het uitvoert.
Deze eenvoudige versie heeft verschillende defecten:
- Je kunt niet tegelijkertijd een reeks submappen maken. Fix: geef de
-p
optie door aanmkdir
. (Dit kan al dan niet wenselijk zijn, aangezien het het risico vergroot dat een typefout onopgemerkt blijft.mkcd mydierctory/newsub
maakt bijvoorbeeld graagmydierctory
enmydierctory/newsub
wanneer unewsub
binnen de bestaandemydirectory
.) - Als het argument begint met
-
maar niet slechts , dan zullenmkdir
encd
het interpreteren als een optie. Als het “gewoon-
is, dan zalcd
het interpreteren als$OLDPWD
. Als het “s+
gevolgd door 0 of meer cijfers, dan zalcd
in zsh het interpreteren als een index in de directory-stack. U kunt het eerste probleem oplossen, maar niet de andere twee, door--
voor het argument door te geven. U kunt al deze problemen oplossen door./
voor het argument te plaatsen als het “een relatief pad is. -
mkdir
volgtCDPATH
niet, maarcd
wel, dus als je “hebt ingesteldCDPATH
naar een waarde die niet “niet begint met.
(een weliswaar enigszins ongebruikelijke configuratie), dan kancd
u naar een andere map brengen dan degene die zojuist is gemaakt.Door./
voor te bereiden op relatieve paden wordt dit opgelost fix (hierdoor wordtCDPATH
genegeerd). - If
mkdir
mislukt, het probeertcd
uit te voeren. Fix: gebruik&&
om de twee commandos te scheiden.
Nog steeds vrij eenvoudig:
mkcd () { case "$1" in /*) :;; *) set -- "./$1";; esac mkdir -p "$1" && cd "$1" }
Deze versie heeft nog steeds het potentieel om cd
naar een andere map te laten gaan dan die dat mkdir
zojuist is gemaakt in één randgeval: als het argument voor mkcd
..
bevat en gaat via een symbolische link. Als de huidige directory bijvoorbeeld /tmp/here
is en mylink
een symbolische link is naar /somewhere/else
, maakt mkdir mylink/../foo
/somewhere/else/foo
aan terwijl cd mylink/../foo
verandert in foo
. Het is niet genoeg om te zoeken naar symbolische links in het argument, omdat de shell ook symbolische links in zijn eigen huidige directory volgt, dus cd /tmp/mylink; mkdir ../foo; cd ../foo
verandert niet in de nieuwe directory (/somewhere/else/foo
) maar in /tmp/foo
. Een oplossing hiervoor is om de ingebouwde cd
alle ..
padcomponenten eerst (het heeft geen “zin om foo/..
te gebruiken als foo
niet” t bestaan, dus mkdir
hoeft nooit ..
) te zien.
We komen tot dit robuuste, zij het enigszins bloederige 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 }
(Oefening: waarom gebruik ik een subshell voor de eerste cd
call?)
Als mkdir mislukt, wil ik er zeker van zijn dat ik de huidige directory niet wijzig. Terugschakelen met cd – of $ OLDPWD is niet goed genoeg als de shell dat niet heeft toestemming om naar de huidige map te gaan. Ook het aanroepen van cd-updates OLDPWD, dus we willen het maar één keer doen (of OLDPWD herstellen).
Er zijn ook minder gespecialiseerde manieren om het woord van de vorige regel niet opnieuw te hoeven typen:
- Typ
cd
en vervolgens Esc . (of Alt + . ) om het laatste argument van het vorige commando in te voegen. -
cd !$
voertcd
uit op het laatste argument van de vorige opdracht. - Druk op Omhoog om de vorige opdrachtregel op te roepen, en bewerk deze dan om
mkdir
te veranderen incd
.
¹ let echter op dat het werkt niet “in ksh93 sinds de u+
versie , opgelost in 93u + m / 1.0.0-alpha + d1483150 2021-01-05
Reacties
- Bedankt! de Esc. lijkt me het handigst, doet de toetsenreeks heb een speciale m eaning?
- Het ‘ is alleen de bash (en geërfd van
ksh
, en werkt ook inzsh
) reeks voor ” herhaal laatste woord van vorige opdracht “. Ik gebruik het vrij vaak. - @Gilles Ik ‘ begin te denken dat de ” Gilles ” -account wordt feitelijk gedeeld door een panel van experts. 😉
- @StephaneChazelas
/a/b/..//
zou echt werken, maar niet/a/b/../c
. Gemaakt. Ik ‘ heb de vraag aan een breder publiek gesteld. -
mkcd() { mkdir -p "$1" && cd "$1"; }
lijkt geen ‘ t een probleem te zijn in (mijn instantie van) 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
(inclusief de setup en) geeft/tmp/here/foo
weer, wat is gemaakt (en wat ik had verwacht).bash
maakt ten onrechte/var/tmp/somewhere/foo
.
Antwoord
Het zou nooit bij me zijn opgekomen om dit gedrag te scripten, omdat ik het volgende bijna elk uur invul …
$ mkdir someDirectory<ENTER> $ cd !$
waar bash vriendelijk !$
vervangt door het laatste woord van de laatste regel; d.w.z. de lange directorynaam die u heeft ingevoerd.
Bovendien is het aanvullen van de bestandsnaam uw vriend in dergelijke situaties. Als je nieuwe map het enige bestand in de map was, zou een snelle dubbele TAB je de nieuwe map geven zonder deze opnieuw in te voeren.
Hoewel het cool is dat bash je toestaat om dergelijke algemene taken te scripten zoals de andere antwoorden suggereren, denk ik dat het beter is om de bewerkingsfuncties van de opdrachtregel te leren die bash te bieden heeft, zodat wanneer je op een andere machine werkt, je de syntactische suiker niet mist die je aangepaste scripts bieden.
Reacties
- Is er een goede plek om meer te weten te komen over de belangrijkste bash-eigenaardigheden zoals deze?
- @ dominicbri7 In het algemeen valt onder ” bash-opdrachtregelbewerking ” Googelen geeft hetzelfde als een topresultaat web.mit.edu/gnu/doc/html/features_7.html Meer specifiek,! $ is een voorbeeld van een Word Designator zie gnu.org/software /bash/manual/bashref.html#Word-Designators
Antwoord
Als u Oh My Zsh, er “een commando genaamd take doet precies dit. Het zou er ongeveer zo uitzien.
take myfolder
Ik heb deze eigenlijk per ongeluk gevonden. Ik heb net gekeken en hij “staat vermeld op deze cheatsheat van de Oh My Zsh GitHub wiki. Het is een behoorlijk nuttige opdracht, en blijkbaar heel gemakkelijk zelf te maken.
Reacties
- Ik wist nooit van
take
🙂 Perfect! btw – iTerm2 met Oh My Zsh. Er zijn hier eigenlijk 3 perfecte antwoorden. Deze, die van @jes ú s-carrera, en het geselecteerde antwoord. Hangt af van uw instellingen en voorkeuren.
Antwoord
Volgens Welke aanpassingen heb je gedaan aan je shell-profiel om de productiviteit te verhogen? , dit is hoe ik het doe:
# make a directory and cd to it mcd() { test -d "$1" || mkdir "$1" && cd "$1" }
het betekent dat het ook werkt als de map al bestaat.
Reacties
- De
-p
optie voor mkdir zal fouten onderdrukken. - mcd is een reeds bestaand commando. Hoewel je ‘ net een voorbeeld hebt gegeven, heb ik het zelf gebruikt omdat het ‘ een letter die korter is dan mkcd.
- @Dharmit Shah: Wat is het bestaande
mcd
commando? Welk pakket of project biedt dit commando? - mtools levert het mcd commando. De man-pagina zegt ” Het mcd-commando wordt gebruikt om de mtools-werkdirectory op de MS-DOS-schijf te wijzigen. ”
Antwoord
Of je kunt gewoon een korte variabele maken en deze twee keer gebruiken x = longproject ; mkdir $x ; cd $x
– wat ik toegeef nog steeds langer is dan het gebruik van een shellscript-functie 🙂
Answer
Dit is een eenvoudig ding om te doen in een bash-script / -functie. Ik heb een zeer leesbare en voldoende gedocumenteerde tutorial gemaakt inclusief scripts die werken op zowel Linux als MacOS (dit zal ook in de toekomst worden onderhouden).
Mijn doel voor de complexiteit van de tutorial is: geschreven voor een gericht publiek met de enige voorwaarde is dat de gebruiker een hartslag heeft en Engels kan lezen, dus geef feedback als je hulp nodig hebt.
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
Om dit te installeren heb je twee opties:
- Ten eerste voegt u de functie toe aan uw
.bashrc
-bestand. - De tweede is om het bestand aan uw pad toe te voegen en plaats het bestand vervolgens in uw
.bash_profile
-bestand.
Nogmaals, het README-bestand is zeer gedetailleerd over hoe u dit moet doen.
Veel succes!
Antwoord
Hier is een kleine variant die het vermelden waard is:
function mkdir() { local dir=$1 command mkdir "$dir" && cd "$dir" }
Voeg dit toe aan yo ur ~/.bash_profile
en je kunt mkdir
zoals normaal gebruiken (zodra je “ve source
” d it), behalve dat het nu de bovenstaande functie zal uitvoeren in plaats van het standaard mkdir
commando.
Let op, dit valideert de invoer niet volgens de geaccepteerde antwoord door Gilles , maar laat zien hoe je ingebouwde onderdelen (effectief) kunt overschrijven.
Van de docs (enigszins parafraserend):
command mkdir [args]
wordt uitgevoerdmkdir
waarbijargs
elke shell-functie met de naammkdir
negeert. Alleen in de shell ingebouwde opdrachten of opdrachten die zijn gevonden door het PATH te doorzoeken, worden uitgevoerd. Als er een shell-functie is met de naamls
, zal het uitvoeren vancommand ls
binnen de functie de externe opdracht uitvoerenls
in plaats van de functie recursief aan te roepen
Ik geloof dat builtin
een vergelijkbaar resultaat behaalt als command
.
Reacties
- je moet zeker
$dir
- @Jeff, akkoord, maar het geaccepteerde antwoord heeft alle validatie die je nodig zou hebben.Ik ‘ presenteer alleen het gebruik van
command
als alternatief. - @Jeff, akkoord, maar het geaccepteerde antwoord heeft alle validatie die je nodig zou hebben.Ik ‘ presenteer alleen het gebruik van
Antwoord
Helperfunctie toevoegen aan BASH, ZSH of KSH
Maak mkcd
commando aan je omgeving in één regel
echo -e "mkcd() {\n mkdir -p "$1" && cd $_\n}" >> ~/.${0//-/}rc && . ~/.${0//-/}rc
Antwoord
Als je Oh-my-zsh gebruikt , take
commando zal het lukken. Bekijk het spiekbriefje .
Antwoord
Gewoon de bovenstaande antwoorden geautomatiseerd en een eenmalig uitvoerbaar script gemaakt:
fun=" mkcd () { mkdir -p -- "$1" && cd -P -- "$1" }" echo "$fun" >> ~/.bashrc
Kopieer dit gewoon in een nieuw bestand mkcd.sh
en voer het slechts één keer uit in terminal door bash mkcd.sh
. Voer vervolgens source ~/.bashrc
uit om het in de huidige sessie te laten werken.
Hierna kunt u mkcd some_dir
gebruiken om en voer rechtstreeks in die map in.
Opmerkingen
- U stelt voor om een script (in een bestand) te schrijven dat als enige doel heeft om toe te voegen aan de
~/.bashrc
bestand (met een antwoord dat al gegeven is)? En hoe stel je voor om ditmkcd.sh
script te maken? Met een redacteur misschien? Dit lijkt meer werk dan alleen het bewerken van~/.bashrc
. Welk voordeel heeft dit ten opzichte van het geaccepteerde antwoord? …………………………………………………………………… P.S. Dit zal mislukken vanwege problemen met citeren, wat me vertelt dat je het zelf niet eens hebt geprobeerd. - Het spijt me te moeten zeggen, maar ja, zoals ik in mijn antwoord schreef, heb ik de bovenstaande antwoorden gebruikt. Het werkt. Als je me niet ‘ gelooft, probeer het dan. En over het niet proberen, ik heb vandaag mijn hele dag gebruikt om dergelijke scripts in bash en python te schrijven.
- Ik heb geprobeerd wat je schreef. Het werkt niet .
mcd
van unix.stackexchange.com/questions/6628/…mkdir longtitleproject
en vervolgenscd !^