Nie mogę powiedzieć, ile razy marzyłem o poleceniu, które zarówno utworzy katalog, jak i przejdzie do tego katalogu. Zasadniczo chciałbym ekwiwalent następujących rzeczy:
mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path
ale wystarczy wpisać /arbitrarily/long/path
raz, coś w stylu:
mk-cd /arbitrarily/long/path
Próbowałem utworzyć skrypt, aby to zrobić, ale zmienia tylko katalog w skrypcie. Chciałbym, aby katalog w powłoce również się zmienił.
#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD
Jak mogę sprawić, żeby to działało?
cd
od razu wybrałeś specjalną skrzynkę. : Dcd
spokrewnione informacje (wróć do poprzedniego katalogu, używająccd -
, używajpushd
ipopd
utrzymując „stos” katalogów): superuser.com/questions/324512/...mkdir -p /very/long/path
, następnie użyćcd
spacji, a następnie naciśnij Alt +,.
aby powtórzyć ostatni argument, tj. Nazwę katalogu.mkdir -p /very/long/path; cd !#:2
. Ciąg!#:2
rozwinie się do argumentu nr. 2 (czyli trzeci argument/very/long/path
, ponieważ liczenie zaczyna się od zera).!$
. Cały czas używam tej konkretnej sztuczki, ale dzięki rozszerzeniu historii możesz zrobić znacznie więcej .Odpowiedzi:
Najprostszym sposobem jest użycie funkcji powłoki:
Umieść go w swoim
.bashrc
pliku, aby był dostępny tak jak inne polecenie powłoki.Powodem, dla którego nie działa jako skrypt zewnętrzny, jest
cd
zmiana bieżącego katalogu uruchomionego skryptu, ale nie wpływa na wywołujący. To jest z założenia! Każdy proces ma własny katalog roboczy, który jest dziedziczony przez jego dzieci, ale odwrotność nie jest możliwa.O ile nie jest częścią potoku, działającą w tle lub jawnie w podpowłoce, funkcja powłoki nie działa w osobnym procesie, ale w tym samym procesie, tak jak w przypadku polecenia. Bieżącą powłokę katalogu można następnie zmienić za pomocą funkcji.
&&
Tutaj stosowane do oddzielania zarówno polecenia stosowane oznacza, że jeśli pierwsze polecenie powiedzie (mkdir
) uruchomienia drugiej (cd
). W konsekwencji, jeślimkdir
nie uda się utworzyć żądanego katalogu, nie ma sensu próbować do niego wchodzić. Komunikat o błędzie jest drukowany przezmkdir
i to wszystko.-p
Opcja wykorzystywanemkdir
są tam, aby powiedzieć to narzędzie do tworzenia wszelkiego brak katalogu, który jest częścią pełnej ścieżki nazwy katalogów przekazany jako argument. Jednym z efektów ubocznych jest to, że jeśli poprosisz o utworzenie już istniejącego katalogu,mkcd
funkcja nie zawiedzie i skończysz w tym katalogu. Można to uznać za problem lub funkcję. W pierwszym przypadku funkcję można zmodyfikować na przykład w taki sposób, aby po prostu ostrzegł użytkownika:Bez tej
-p
opcji zachowanie funkcji początkowej wyglądałoby zupełnie inaczej.Jeśli katalog zawierający katalog do utworzenia nie istnieje,
mkdir
oznacza to awarię i funkcja.Jeśli katalog, który ma zostać utworzony, już istnieje,
mkdir
również zawiedzie icd
nie zostanie wywołany.Na koniec zauważ, że ustawienie / eksportowanie
PWD
jest bezcelowe, ponieważ powłoka już to robi wewnętrznie.Edycja: Dodałem
--
opcję do obu poleceń dla funkcji, aby zezwolić na nazwę katalogu zaczynającą się od myślnika.źródło
~/.bashrc
jednego z innych skryptów inicjalizacyjnych lub jednego z nich.alias mk-cd 'mkdir -p \!:1; cd \!:1'
bez funkcji? A może powinienem zacząć myśleć o funkcjach bash bardziej jak o rozszerzonych aliasach?csh
mechanizm przekazywania argumentów nie jest implementowany z aliasami typu bourne. Funkcje są rzeczywiście właściwą drogą, ponieważ są znacznie bardziej elastyczne.bar
). Inną opcją byłoby użyciehistory 1
, jak walias mk-cd='args="$(history 1)" && args="${args#*mk-cd\ }" && mkdir -p "$args" && cd'
- działa to dobrze dla przykładu pytającego, ale nie jest to ogólne rozwiązanie, ponieważ wszelkie inne polecenia w tym samym wierszu (np. Potokowanie wyjścia) spowodują jego awarię.Chciałbym dodać alternatywne rozwiązanie.
Twój skrypt będzie działał, jeśli wywołasz go za pomocą polecenia
.
lubsource
:Jeśli to zrobisz,
export
skrypt nie będzie potrzebny. Możesz pominąć wpisywanie.
za pomocąalias
:Powodem tego jest to, że skrypt normalnie działa w podpowłoce, więc środowisko jest tracone po zakończeniu, ale polecenie
.
(lubsource
) zmusza go do działania w bieżącej powłoce.Ta technika może być przydatna w przypadku sekwencji poleceń, które są zbyt skomplikowane dla funkcji lub są w trakcie opracowywania i są często edytowane: po
alias
wprowadzeniu.bash_aliases
można edytować skrypt w dowolnej chwili bez ponownej inicjalizacji.Uwaga:
Jeśli napiszesz skrypt, który należy wywołać za pomocą polecenia
.
/source
, możesz to sprawdzić na dwa sposoby: -Z jakiegoś powodu skrypt wywołany z
.
/source
nie musi być wykonywalny, więc po prostu usuń to uprawnienie, a skrypt albo nie zostanie znaleziony w „$ PATH”, albo da błąd uprawnień, jeśli zostanie wywołany z jawną ścieżką.Alternatywnie, na początku skryptu można zastosować następującą sztuczkę:
Działa to, ponieważ w podpowłoce
bind
generuje ostrzeżenie, ale nie ma statusu błędu: dlategoread
jest używany do dawania błędu przy braku danych wejściowych.źródło
.
. Robiłem. .bashrc
niezliczoną ilość razy, ale nie wiedziałem, co dokładnie.
robi. Czy to jest podobne doexport
?export var
kopiuje zmienną wewnętrznąvar
do środowiska, gdzie jest dziedziczona i importowana jako zmienna w dowolnej podpowłoce, ale nie ma wpływu na powłokę nadrzędną. Zwykle tworzona jest podpowłoka w celu uruchomienia skryptu, a wszelkie wprowadzane przez nią zmiany (w tym zmienne eksportowane) są tracone po zakończeniu. Aby skrypt ustawiał zmienne w powłoce, musi on działać w tej powłoce, a to właśnie.
robi polecenie: uruchom skrypt bez tworzenia podpowłoki. Co ciekawe, uruchamiane skrypty.
nie muszą mieć uprawnień do wykonywania..
iexport
, tytuł tego pytania nie skłoniłby cię do oczekiwania tutaj odpowiedzi, więc niech moja odpowiedź pozostanie bez zmian, ale dziękuję za komentarz.Nie jest to jedno polecenie, ale nie musisz ponownie wpisywać wszystkich ścieżek, których używasz
!$
(co jest ostatnim argumentem z poprzedniego polecenia w historii powłoki).Przykład:
źródło
Tworząc aliasy . Bardzo popularny sposób tworzenia własnych poleceń.
Możesz utworzyć alias w locie:
Otóż to. Jeśli chcesz zachować ten alias na stałe (nie tylko bieżącą sesję), umieść to polecenie w pliku kropkowym (zwykle ~ / .bash_aliases lub ~ / .bash_profile).
źródło
Oprócz tego, co już zostało zasugerowane, chciałbym polecić kurwa . Jest to środowisko Python usprawniające proces powłoki przez naprawianie błędów. Zainspirowany tym tweetem , wszystko co musisz zrobić, to wpisać skonfigurowany alias (domyślnie
fuck
) i spróbujesz poprawić poprzednie polecenie. Jedna z jej poprawek zachowuje się następująco:źródło