Czy istnieje jedna linijka, która pozwala mi utworzyć katalog i przenieść się do niego w tym samym czasie?

Często powtarzam:

 mkdir longtitleproject cd longtitleproject  

Czy można to zrobić w jednej linii bez powtarzania nazwy katalogu? Jestem na bash tutaj.

Komentarze

Odpowiedź

To jest jednowierszowy, którego potrzebujesz. Żadna inna konfiguracja nie jest wymagana:

mkdir longtitleproject && cd $_ 

Zmienna $_ w bash, jest ostatnim argumentem przekazanym poprzedniej komendzie. W tym przypadku nazwa właśnie utworzonego katalogu. Jak wyjaśniono w 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. 

Użyj cd $_, aby pobrać ostatni argument z poprzedniego polecenia zamiast cd !$, ponieważ cd !$ podaje ostatni argument poprzedniego polecenia w historii powłoki :

cd ~/ mkdir folder && cd !$ 

kończysz w domu (lub ~ /)

cd ~/ mkdir newfolder && cd $_ 

kończysz w nowym folderze pod domem !! (lub ~ / newfolder)

Komentarze

  • Dlaczego, u licha, ta odpowiedź nie jest akceptowaną odpowiedzią
  • @JSmyth Zgadzam się , jest to jednowierszowy, który wykorzystuje natywną funkcjonalność powłoki
  • Myślę, że OP próbuje unikać używania tych dwóch poleceń. Ta odpowiedź jest (prawie) tak samo ważna jak zrobienie mkdir foo && cd foo, co nie jest ' t poręczne.
  • OP jest prośba o jedną linijkę, która nie ' nie wymaga powtarzania nazwy katalogu, i to jest to
  • Głos za nim ' jest oczywiste, że wiele osób uważa tę odpowiedź za przydatną. ' powiem, dlaczego nie ' nie wybrałem tej odpowiedzi: I ' m bardzo prawdopodobnie błędnie wpiszemy && cd $_, ponieważ klawisze są tak daleko od wiersza głównego, więc chociaż technicznie poprawne, ' nie jest ergonomiczne. Doceniam fakt, że ' nie zależy od środowiska i ' warto wiedzieć. Dzięki!

Odpowiedź

Nie ma wbudowanego polecenia, ale możesz łatwo napisać funkcję, która wywołuje mkdir, a następnie cd:

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

Wpisz ten kod Twój plik ~/.bashrc (lub ~/.kshrc dla użytkowników ksh lub ~/.zshrc dla użytkowników zsh). Definiuje funkcję o nazwie mkcd. "$1" zostanie zastąpiona argumentem funkcji po jej uruchomieniu.

Ta prosta wersja ma kilka wad:

  • Nie możesz utworzyć łańcucha podkatalogów naraz. Poprawka: przekaż opcję -p do . (Może to być pożądane lub nie, ponieważ zwiększa ryzyko niezauważenia literówki, np. mkcd mydierctory/newsub z radością utworzy mydierctory i mydierctory/newsub, gdy zamierzałeś utworzyć newsub wewnątrz istniejący mydirectory.)
  • Jeśli argument zaczyna się od -, ale nie jest „t tylko -, a następnie mkdir i cd zinterpretują to jako opcję. Jeśli to tylko -, to cd zinterpretuje to jako $OLDPWD. Jeśli to „s +, po którym następuje 0 lub więcej cyfr, a następnie cd w zsh zinterpretuje to jako indeks w stosie katalogów. Możesz rozwiązać pierwszy problem, ale nie dwa pozostałe, przekazując -- przed argumentem. Możesz naprawić wszystkie te problemy, dodając ./ do argumentu, jeśli jest to ścieżka względna.
  • mkdir nie „t śledzi CDPATH, ale cd tak, więc jeśli ustawiłeś CDPATH do wartości, która nie „t zaczyna się od . (jest to dość nietypowa konfiguracja), to cd może przenieść Cię do innego katalogu niż ten, który właśnie został stworzony.Dodanie ./ do ścieżek względnych rozwiązuje ten problem¹ (powoduje ignorowanie CDPATH).
  • Jeśli nie powiodło się, próba wykonania cd. Poprawka: użyj &&, aby oddzielić te dwa polecenia.

Wciąż dość proste:

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

Ta wersja nadal może spowodować, że cd przejdzie do innego katalogu niż ten że mkdir właśnie utworzony w jednym przypadku: jeśli argument mkcd zawiera .. i przechodzi przez dowiązanie symboliczne. Na przykład, jeśli bieżący katalog to /tmp/here, a mylink to symboliczne łącze do /somewhere/else , a następnie mkdir mylink/../foo tworzy /somewhere/else/foo, podczas gdy cd mylink/../foo zmienia się w foo. Nie wystarczy szukać dowiązań symbolicznych w argumencie, ponieważ powłoka śledzi również dowiązania symboliczne w swoim własnym bieżącym katalogu, więc cd /tmp/mylink; mkdir ../foo; cd ../foo nie przechodzi do nowego katalogu (/somewhere/else/foo), ale do /tmp/foo. Rozwiązaniem tego problemu jest umożliwienie wbudowanemu cd rozwiązaniu wszystkich .. najpierw komponenty ścieżki (nie ma sensu używać foo/.. jeśli foo nie ma ” nie istnieje, więc mkdir nigdy nie musi widzieć żadnego ..).

Dochodzimy do tego solidnego, choć nieco krwawego wersja:

 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 }  

(Ćwiczenie: dlaczego używam podpowłoki do pierwszego cd call?)

Jeśli mkdir zawiedzie, nie chcę zmieniać bieżącego katalogu. Zmiana z powrotem za pomocą cd – lub $ OLDPWD nie jest wystarczająco dobra, jeśli powłoka tego nie robi uprawnienie do przejścia do bieżącego katalogu. Ponadto wywołanie aktualizacji CD OLDPWD, więc chcemy to zrobić tylko raz (lub przywrócić OLDPWD).


Są też mniej wyspecjalizowane sposoby aby nie trzeba było ponownie wpisywać słowa z poprzedniego wiersza:

  • Wpisz cd , a następnie Esc . (lub Alt + . ), aby wstawić ostatni argument z poprzedniego polecenia.
  • cd !$ wykonuje cd na ostatnim argumencie poprzedniego polecenia.
  • Naciśnij W górę , aby przywołać poprzednią linię poleceń, a następnie edytuj ją zmienić mkdir na cd.

¹ uważaj jednak, że nie działa w ksh93 od u+ wersji , poprawiona w 93u + m / 1.0.0-alpha + d1483150 05.01.2021

Komentarze

  • Dzięki! Esc wydaje mi się najwygodniejszy, czy sekwencja klawiszy mają jakieś specjalne m eaning?
  • To ' to tylko Bash (i dziedziczone z ksh, a także działa w zsh) dla ” powtórz ostatnie słowo poprzedniego polecenia „. Używam go dość często.
  • @Gilles I ' zaczynam myśleć, że ” Gilles ” jest faktycznie wspólne dla panelu ekspertów. 😉
  • @StephaneChazelas /a/b/..// faktycznie działałoby, ale nie /a/b/../c. Naprawiony. ' zadałem pytanie szerszej publiczności.
  • mkcd() { mkdir -p "$1" && cd "$1"; } nie ' wydaje się być problemem w (moim wystąpieniu) 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 (zawiera konfigurację i) wyświetla /tmp/here/foo, co zostało utworzone (i czego się spodziewałem). bash błędnie tworzy i zmienia na /var/tmp/somewhere/foo.

Odpowiedź

Nigdy nie przyszło mi do głowy, aby napisać skrypt tego zachowania, ponieważ wprowadzam następujące informacje prawie co godzinę …

$ mkdir someDirectory<ENTER> $ cd !$ 

gdzie bash uprzejmie zastępuje !$ ostatnim słowem ostatniej linii; tj. długa nazwa katalogu, którą wprowadziłeś.

Ponadto uzupełnianie nazw plików jest twoim przyjacielem w takich sytuacjach. Jeśli twój nowy katalog był jedynym plikiem w folderze, szybkie podwójne TAB wskaże ci nowy katalog bez ponownego wprowadzania go.

Chociaż to fajne, że bash pozwala ci aby napisać takie typowe zadania, jak sugerują inne odpowiedzi, myślę, że lepiej jest nauczyć się funkcji edycji wiersza poleceń, które ma do zaoferowania bash, aby podczas pracy na innym komputerze nie tracić cukru składniowego, który zapewniają niestandardowe skrypty.

Komentarze

Odpowiedź

Jeśli używasz O mój Zsh, jest „polecenie o nazwie take , które robi dokładnie to. Wyglądałoby mniej więcej tak.

take myfolder 

To przypadek, które znalazłem. Właśnie spojrzałem i jest wymienione na ten cheatsheat z wiki Oh My Zsh GitHub. To całkiem przydatne polecenie i najwyraźniej bardzo łatwe do samodzielnego utworzenia.

Komentarze

  • Nigdy nie wiedziałem o take 🙂 Idealnie! btw – iTerm2 z Oh My Zsh. W rzeczywistości są tutaj 3 doskonałe odpowiedzi. Ta, ta autorstwa @jes ú s-carrera, i wybrana odpowiedź. Zależy od konfiguracji i preferencji.

Odpowiedź

Zgodnie z Jakich dostosowań dokonałeś w swoim profilu powłoki, aby zwiększyć produktywność? , tak to robię:

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

oznacza to, że działa również, jeśli katalog już istnieje.

Komentarze

  • Opcja -p w mkdir zablokuje błędy.
  • mcd to już istniejące polecenie. Chociaż ' właśnie podałeś przykład, użyłem go samodzielnie, ponieważ ' to litera krótsza niż mkcd.
  • @Dharmit Shah: Jakie jest istniejące polecenie mcd? Który pakiet lub projekt udostępnia to polecenie?
  • mtools udostępnia polecenie mcd. Jego strona podręcznika mówi ” Polecenie mcd jest używane do zmiany katalogu roboczego mtools na dysku MS-DOS. ”

Odpowiedź

Lub możesz po prostu utworzyć krótką zmienną w locie i użyć jej dwukrotnie x = longproject ; mkdir $x ; cd $x – co, przyznaję, jest nadal dłuższe niż użycie funkcji skryptu powłoki 🙂

Odpowiedź

To jest prosta rzecz do zrobienia w skrypcie / funkcji basha. Stworzyłem bardzo czytelny i wystarczająco udokumentowany samouczek zawierający skrypty, które działają zarówno na Linuksie, jak i MacOS (będzie to również utrzymywane w przyszłości).

Moim celem w zakresie złożoności samouczka jest: napisanie dla docelowych odbiorców z jedynym warunkiem wstępnym jest to, że użytkownik ma puls i potrafi czytać po angielsku, więc jeśli potrzebujesz pomocy, prześlij opinię.

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  

Do zainstalowania masz dwa opcje:

  • Najpierw dodaj funkcję do pliku .bashrc.
  • Po drugie, dodaj plik do ścieżki a następnie zbierz plik z pliku .bash_profile.

Ponownie, plik README zawiera bardzo szczegółowe informacje, jak to zrobić.

Powodzenia!

Odpowiedź

Oto niewielki wariant, o którym warto wspomnieć:

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

Dodaj to do siebie ur ~/.bash_profile i możesz wtedy normalnie używać mkdir (gdy już „ve source” d it), z wyjątkiem tego, że teraz uruchomi powyższą funkcję zamiast standardowego polecenia mkdir.

Uwaga, to nie sprawdza poprawności danych wejściowych zgodnie z zaakceptowanym odpowiedź Gillesa , ale pokazuje, jak (skutecznie) przesłonić wbudowane.

Z dokumenty (lekko parafrazując):

command mkdir [args] działa mkdir z args ignorującymi jakąkolwiek funkcję powłoki o nazwie mkdir. Wykonywane są tylko polecenia wbudowane lub polecenia znalezione podczas przeszukiwania PATH. Jeśli istnieje funkcja powłoki o nazwie ls, uruchomienie command ls w ramach tej funkcji spowoduje wykonanie zewnętrznego polecenia ls zamiast rekurencyjnego wywoływania funkcji

Uważam, że builtin daje podobny wynik do command.

Komentarze

  • zdecydowanie należy zacytować $dir
  • @Jeff, zgodził się, ale zaakceptowana odpowiedź ma wszystko, czego potrzeba.' m tylko przedstawiam użycie command jako alternatywy.

Odpowiedź

Dodawanie funkcji pomocniczej do BASH, ZSH lub KSH

Utwórz polecenie mkcd w swoim środowisku w jedna linia

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

Odpowiedź

Jeśli używasz Oh-my-zsh , polecenie take załatwi sprawę. Spójrz na ściągawki .

Odpowiedź

Zautomatyzowałem powyższe odpowiedzi i utworzyłem jednorazowy skrypt wykonywalny:

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

Po prostu skopiuj to do nowego pliku mkcd.sh i uruchom go tylko raz w terminalu przez bash mkcd.sh. Następnie wykonaj source ~/.bashrc, aby działał w bieżącej sesji.

Następnie możesz użyć mkcd some_dir, aby utworzyć i wejdź bezpośrednio do tego katalogu.

Komentarze

  • Sugerujesz napisanie skryptu (w pliku), którego jedynym celem jest dołączenie do ~/.bashrc plik (z już udzieloną odpowiedzią)? A jak sugerujesz utworzenie tego mkcd.sh skryptu? Może z redaktorem? Wygląda na to, że wymaga więcej pracy niż tylko edytowanie ~/.bashrc. Jaką ma to przewagę nad zaakceptowaną odpowiedzią? …………………………………………………………………… P.S. To się nie powiedzie z powodu problemów z cytowaniem, co oznacza, że sam nawet tego nie próbowałeś.
  • Przykro mi to mówić, ale tak, jak napisałem w mojej odpowiedzi, użyłem powyższych odpowiedzi. To działa. Jeśli nie ' mi nie wierzysz, spróbuj. A żeby nie próbować, wykorzystałem cały dzień na pisanie takich skryptów w bashu i pythonie dzisiaj.
  • Spróbowałem tego, co napisałeś. To nie działa.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *