Existuje jednorázová linka, která mi umožňuje vytvořit adresář a současně se do něj přesunout?

Zjistil jsem, že hodně opakuji:

 mkdir longtitleproject cd longtitleproject  

Existuje způsob, jak to udělat v jednom řádku bez opakování názvu adresáře? Tady jsem bash.

Komentáře

Odpověď

Toto je ten jeden liner, který potřebujete. Není potřeba žádná další konfigurace:

mkdir longtitleproject && cd $_ 

Proměnná $_ v bash, je poslední argument zadaný předchozímu příkazu. V tomto případě název adresáře, který jste právě vytvořili. Jak je vysvětleno v 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. 

Pomocí cd $_ načtěte poslední argument předchozí příkaz namísto cd !$ protože cd !$ dává poslední argument předchozího příkazu v historii prostředí :

cd ~/ mkdir folder && cd !$ 

skončíte doma (nebo ~ /)

cd ~/ mkdir newfolder && cd $_ 

skončíte v nové složce pod domovem !! (nebo ~ / newfolder)

Komentáře

  • Proč na Zemi tohle není přijatá odpověď
  • @JSmyth Souhlasím , toto je jednorázová linka, která používá nativní funkčnost shellu.
  • Myslím, že OP se snaží vyhnout použití těchto dvou příkazů. Tato odpověď je (téměř) stejně platná jako mkdir foo && cd foo, což není ‚ praktické.
  • OP je žádá o liniovou linku, která ‚ nevyžaduje opakování názvu adresáře, a to je to
  • podle upvotes ‚ Je zřejmé, že mnoho lidí považuje tuto odpověď za užitečnou. Já ‚ uvedu, proč jsem ‚ nevybral tuto odpověď: ‚ m very pravděpodobně se zadá nesprávně && cd $_, protože klíče jsou tak daleko od domovské řady, takže i když je to technicky správné, není to ‚ ergonomické. Oceňuji skutečnost, že to ‚ není závislé na prostředí a je to užitečné ‚. Děkujeme!

Odpověď

Neexistuje žádný vestavěný příkaz, ale můžete snadno napsat funkci, která volá mkdir poté cd:

mkcd () { mkdir "$1" cd "$1" } 

Vložte tento kód do váš ~/.bashrc soubor (nebo ~/.kshrc pro uživatele ksh nebo ~/.zshrc pro uživatele zsh). Definuje funkci s názvem mkcd. "$1" bude při spuštění nahrazen argumentem funkce.

Tato jednoduchá verze má několik vad:

  • Nelze vytvořit řetězec podadresářů najednou. Oprava: předat možnost -p do mkdir. (To může nebo nemusí být žádoucí, protože to zvyšuje riziko nezjištěného překlepu, např. mkcd mydierctory/newsub šťastně vytvoří mydierctory a mydierctory/newsub, když jste chtěli vytvořit newsub uvnitř existující mydirectory.)
  • Pokud argument začíná -, ale pouze -, pak mkdir a cd jej interpretují jako jednu z možností. Pokud je to jen -, pak cd to bude interpretovat tak, že to bude znamenat $OLDPWD. to „s + následované 0 nebo více číslicemi, pak cd v zsh to interpretuje jako index v zásobníku adresářů. První problém, ale ne další dva, můžete vyřešit předáním -- před argumentem. Všechny tyto problémy můžete vyřešit tak, že před argument ./ použijete relativní cestu.
  • mkdir nedodržuje CDPATH, ale cd ano, takže pokud nastavíte CDPATH na hodnotu, která nezačíná . (sice poněkud neobvyklou konfigurací), pak vás cd může přivést do jiného adresáře než ten, který byl právě vytvořen.Příprava ./ na relativní cesty to napraví1 (způsobí to ignorování CDPATH).
  • Pokud mkdir selže, pokusí se spustit cd. Oprava: Použijte && k oddělení dvou příkazů.

Stále celkem jednoduché:

 mkcd () { case "$1" in /*) :;; *) set -- "./$1";; esac mkdir -p "$1" && cd "$1" }  

Tato verze má stále potenciál přimět cd přejít do jiného adresáře, než je ten že mkdir právě vytvořeno v jednom případě okraje: pokud argument mkcd obsahuje .. a prochází symbolickým odkazem. Pokud je například aktuální adresář /tmp/here a mylink symbolický odkaz na /somewhere/else , pak mkdir mylink/../foo vytvoří /somewhere/else/foo zatímco cd mylink/../foo se změní na foo. Nestačí hledat symbolické odkazy v argumentu, protože shell sleduje také symbolické odkazy ve svém vlastním aktuálním adresáři, takže cd /tmp/mylink; mkdir ../foo; cd ../foo se nezmění na nový adresář (/somewhere/else/foo), ale do /tmp/foo. Oprava spočívá v tom, že cd vestavěné řešení vyřeší všechny .. nejprve komponenty cesty (nemá smysl používat foo/.. pokud foo není “ neexistují, takže mkdir nikdy nepotřebuje vidět žádné ..).

Přišli jsme k tomuto robustnímu, pokud trochu krutému verze:

 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 }  

(Cvičení: Proč používám subshell pro první cd volání?)

Pokud selže mkdir, chci mít jistotu, že nezměníte aktuální adresář. Změna zpět pomocí cd – nebo $ OLDPWD není dost dobrá, pokud shell nemá oprávnění ke změně do aktuálního adresáře. Volání CD také aktualizuje OLDPWD, takže to chceme udělat jen jednou (nebo obnovit OLDPWD).


Existují i méně specializované způsoby nemusíte znovu psát slovo z předchozího řádku:

  • Napište cd a poté Esc . (nebo Alt + . ) pro vložení posledního argumentu z předchozího příkazu.
  • cd !$ provede cd na posledním argumentu předchozího příkazu.
  • Stisknutím Nahoru vyvoláte předchozí příkazový řádek a poté jej upravíte změnit mkdir na cd.

¹ pozor, nicméně nefunguje v ksh93 od verze u+ , opravené v 93u + m / 1.0.0-alfa + d1483150 2021-01-05

Komentáře

  • Díky! Esc. se mi zdá nejvhodnější, dělá klíčovou sekvenci mít nějaké speciální m eaning?
  • Je to ‚ pouze Bash (a zděděno z ksh a funguje také v zsh) sekvence pro “ opakování posledního slova předchozího příkazu „. Používám to docela často.
  • @Gilles I ‚ m si začínám myslet, že “ Gilles “ účet ve skutečnosti sdílí panel odborníků. 😉
  • @StephaneChazelas /a/b/..// by ve skutečnosti fungoval, ale ne /a/b/../c. Pevný. Položil jsem ‚ otázku širšímu publiku.
  • mkcd() { mkdir -p "$1" && cd "$1"; } se ‚ nejeví jako problém v (mém případě) 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 (zahrnuje nastavení a) zobrazí /tmp/here/foo což je to, co bylo vytvořeno (a co jsem očekával). bash chybně vytvoří a změní /var/tmp/somewhere/foo.

Odpovědět

Nikdy by mě nenapadlo skriptovat toto chování, protože zadávám následující téměř každou hodinu …

$ mkdir someDirectory<ENTER> $ cd !$ 

kde bash laskavě nahradí !$ posledním slovem posledního řádku; tj. dlouhý název adresáře, který jste zadali.

Navíc je v takových situacích vaším přítelem doplnění názvu souboru. Pokud byl váš nový adresář jediným souborem ve složce, rychlá dvojitá TAB vám poskytne nový adresář, aniž byste jej museli znovu zadávat.

Ačkoli je skvělé, bash vám umožňuje skriptovat takové běžné úkoly, jak naznačují další odpovědi, myslím, že je lepší naučit se funkce úprav příkazového řádku, které bash nabízí, takže při práci na jiném stroji vám nebude chybět syntaktický cukr, který poskytují vaše vlastní skripty.

Komentáře

odpověď

Pokud používáte Ach můj Zsh, existuje příkaz s názvem take , který dělá přesně toto. Vypadalo by to asi takto.

take myfolder 

Tento jsem vlastně našel náhodou. Jen jsem se podíval a je uveden na this cheatsheat z wiki stránky Oh My Zsh GitHub. Je to docela užitečný příkaz a zdá se, že je velmi snadné ho vytvořit.

Komentáře

  • Nikdy jsem o 🙂 Perfektní! btw – iTerm2 s Oh My Zsh. Ve skutečnosti existují 3 perfektní odpovědi. Tahle, ta od @jes ú s-carrera a vybraná odpověď. Závisí na vašem nastavení a preferencích.

Odpověď

Podle Jaká přizpůsobení jste provedli ve svém shell profilu pro zvýšení produktivity? , takto to dělám:

# make a directory and cd to it mcd() { test -d "$1" || mkdir "$1" && cd "$1" } 

to znamená, že funguje také v případě, že adresář již existuje.

Komentáře

  • Možnost -p pro mkdir potlačí chyby.
  • mcd je již existující příkaz. Ačkoli jste ‚ uvedli příklad, použil jsem ho sám jako ‚ sa písmeno kratší než mkcd.
  • @Dharmit Shah: Co je existující příkaz mcd? Který balíček nebo projekt poskytuje tento příkaz?
  • mtools poskytuje příkaz mcd. Jeho ruční stránka říká “ Příkaz mcd se používá ke změně pracovního adresáře mtools na disku MS-DOS. “

Odpověď

Nebo můžete jednoduše vytvořit krátkou proměnnou za běhu a použít ji dvakrát x = longproject ; mkdir $x ; cd $x – což připouštím, že je stále delší než použití funkce shecriptcript 🙂

Odpověď

Toto je jednoduchá věc v bash skriptu / funkci. Vytvořil jsem velmi čitelný a dostatečně zdokumentovaný výukový program včetně skriptů, které fungují v systémech Linux i MacOS (toto bude zachováno i v budoucnu).

Mým cílem pro složitost výuky je: napsáno pro cílové publikum s jediným předpokladem je, že uživatel má puls a umí číst anglicky, proto prosím poskytněte zpětnou vazbu, pokud potřebujete pomoc.

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  

Chcete-li jej nainstalovat, máte dva možnosti:

  • Nejprve přidejte funkci do svého .bashrc souboru.
  • Druhým je přidání souboru do vaší cesty a poté jej nahrajte do souboru .bash_profile.

Soubor README je opět velmi podrobný, jak to udělat.

Hodně štěstí!

Odpověď

Zde je nepatrná varianta, která stojí za zmínku:

function mkdir() { local dir=$1 command mkdir "$dir" && cd "$dir" } 

Přidejte toto mezi své ur ~/.bash_profile a poté můžete mkdir použít jako obvykle (jakmile „ve source“ d it), až na to, že nyní spustí výše uvedenou funkci, nikoli standardní příkaz mkdir.

Poznámka: toto neověřuje vstup podle přijatého odpověď Gillese , ale ukazuje, jak můžete (efektivně) přepsat vestavěné prvky.

Z dokumenty (mírně parafrázující):

command mkdir [args] běží mkdir s args ignorováním jakékoli funkce shellu s názvem mkdir. Spustí se pouze vestavěné příkazy shellu nebo příkazy nalezené prohledáním PATH. Pokud existuje funkce shellu s názvem ls, spuštění command ls v rámci této funkce provede externí příkaz ls místo rekurzivního volání funkce

Věřím, že builtin dosáhne podobného výsledku jako command.

Komentáře

  • měli byste určitě citovat $dir
  • @Jeff, souhlasil, ale přijatá odpověď má veškerou validaci, kterou by člověk potřeboval.‘ Představuji použití command jako alternativy.

Odpověď

Přidání pomocné funkce do BASH, ZSH nebo KSH

Vytvořte do svého prostředí příkaz mkcd v jeden řádek

echo -e "mkcd() {\n mkdir -p "$1" && cd $_\n}" >> ~/.${0//-/}rc && . ~/.${0//-/}rc 

odpověď

Pokud používáte Oh-my-zsh , take příkaz provede trik. Podívejte se na cheat sheet .

Odpovědět

Výše uvedené odpovědi automatizoval a vytvořil jednorázový spustitelný skript:

fun=" mkcd () { mkdir -p -- "$1" && cd -P -- "$1" }" echo "$fun" >> ~/.bashrc 

Stačí je zkopírovat do nového souboru mkcd.sh a spustit jej pouze jednou v terminálu bash mkcd.sh. Poté proveďte source ~/.bashrc, aby to v aktuální relaci fungovalo.

Poté můžete pomocí mkcd some_dir vytvořit a zadejte přímo do tohoto adresáře.

Komentáře

  • Navrhujete napsat skript (do souboru), jehož jediným účelem je připojit k ~/.bashrc soubor (s odpovědí, která již byla uvedena)? A jak navrhujete vytvoření tohoto skriptu mkcd.sh? Možná s editorem? Vypadá to jako více práce než jen úpravy ~/.bashrc. Jakou výhodu to má oproti přijaté odpovědi? ……………………………………………………………………… P.S. To selže kvůli problémům s citováním, které mi říkají, že jste to sami ani nezkoušeli.
  • Omlouvám se, ale ano, jak jsem napsal ve své odpovědi, použil jsem výše uvedené odpovědi. Funguje to. Pokud mi ‚ nevěříte, zkuste to. A abych to nezkusil, použil jsem celý svůj den k tomu, abych dnes psal takové skripty v bash a pythonu.
  • Zkusil jsem to, co jsi napsal. To nefunguje .

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *