Czy „,,” można nazwać „..”?

41

Czasami, gdy chcę zmienić katalog nadrzędny, błędnie wpisuję cd ,,zamiast cd ... Czy jest jakiś sposób, w jaki bash może uznać te stwierdzenia za takie same? W moich poleceniach nigdy nie używam przecinków. Idealnie, chciałbym aliasu ,,do ... Kiedy to spróbowałem, nie zadziałało. Dlaczego to nie zadziałało? Jak inaczej mogę podejść do tego problemu?

$ alias ,,=..
$ cd ,,
-bash: cd: ,,: No such file or directory
kilodżuli
źródło
6
Alias ​​to program do uruchomienia, a nie argument do programu; tak $ ,,by narzekać, takie jak: bash: ..: Is a directory. (Innymi słowy, nie jest to plik wykonywalny.)
jpaugh
5
@jpaugh: Wyraźniejszy sposób mówienia, że: rozszerzenie aliasu ma miejsce tylko przy pierwszym „słowie” polecenia. Tak jak mówisz, działa tylko dla nazw poleceń, a nie dla argumentów. (I nawet nie mógłbyś alias 'cd ,,'='cd ..'. Cóż, mógłbyś, ale musiałbyś go uruchomić, cd\ ,,żeby to wszystko było jednym słowem.)
Peter Cordes
5
Rozważmy zsh. Ma globalne aliasy, więc alias -g ,,=..i cd ,,działa zgodnie z oczekiwaniami.
muru
1
Myślenie boczne: find / -type d -exec ln -s .. {}/,, \;... ;-)
Toby Speight
2
Imho: nie rób tego. Używanie aliasów do ukrywania błędów typograficznych to zła praktyka. Błędy te mogą skończyć się wklejonym kodem lub screencastami. Nie będzie działać na innych hostach lub kontach. Taka modyfikacja (w zależności od sposobu jej implementacji) może spowodować inne, nieoczekiwane, trudne do debugowania błędy. Moja sugestia: jeśli pomylisz polecenie, wpisz je ponownie ;-).
jjmontes

Odpowiedzi:

45

ZSH:

Jeśli korzystasz z zsh alias -g ,,=".."tego, czego potrzebujesz, ale spowoduje to rozszerzenie „,,” wszędzie, nie tylko w połączeniu z cd.

Od man zshbuiltins:

Jeśli -g flaga jest obecna, zdefiniuj alias globalny; aliasy globalne są rozwijane, nawet jeśli nie występują w pozycji polecenia.

GRZMOTNĄĆ:

Jeśli jest to ograniczone bash(ponieważ pytanie jest oznaczone tagiem ), przeczytaj następujące informacje:

Jest to rozwiązanie czysto aliasowe, zgodnie z żądaniem, jednak będzie to więcej niż wymagało, prawdopodobnie frustrujące użytkownika (zobacz ostrzeżenie na końcu mojego postu).

Cytat man bash:

Jeśli ostatni znak wartości aliasu jest pusty, to następne słowo polecenia następujące po aliasie jest również sprawdzane pod kątem rozszerzenia aliasu.

Dlatego wystarczy alias cdz dodatkową spacją (aby umożliwić rozwinięcie następnego argumentu), a następnie alias ,,do ... Zobaczyć, że

alias cd='cd '
alias ,,='..'

daje dokładnie to, czego potrzebujesz.

Zauważ, że jest to poprawne nie tylko dla bash(i jego aliasimplementacji), ale dla wszystkich powłok kompilujących POSIX. Cytując przykład z man 1p alias(podręcznik nie opisuje tej funkcji wyraźnie, tylko na przykładzie):

  1. Ustaw nohup tak, aby mógł sobie poradzić z argumentem, który sam jest nazwą aliasu:

           alias nohup="nohup "

Ostrzeżenie: Jak pisze @PeterCordes w swoim komentarzu, spowoduje to automatyczne rozszerzenie innych aliasów po zapisaniu cd. Może zaistnieć potrzeba napisania, cd \grepjeśli chcesz zmienić katalog na inny, grepale twój grepjest aliasem dla grep --color=auto. Bez odwrotnego ukośnika cdzgłosi błąd „zbyt wiele argumentów” (nie można cddwóch katalogów naraz) !.

mucha styropianowa
źródło
22
To sprytny, ale paskudny hack. Nie chciałbym tego robić; zbyt łatwo, aby przypadkowo cię ugryźć. np. jeśli masz alias dla polecenia, które zwykle uruchamiasz, i chcesz cdwejść do katalogu jego kodu źródłowego. Lub inne kolizje między twoimi aliasami a popularnymi nazwami katalogów. Podobnie cd drjak cd disown -rdla mnie, z tym pseudonimem. W każdym razie o wiele lepiej jest zastąpić wbudowaną cdfunkcję dla rzeczy takich jak IMO.
Peter Cordes
8
+1 dla rozwiązania czystego aliasu (dowiedziałem się czegoś). Jednocześnie zgadzam się z komentarzem Petera. Myślę, że do twojej odpowiedzi należy dodać jakieś wyraźne ostrzeżenie.
Kamil Maciorowski
58

Aliasy nie mają tego robić, ale możesz utworzyć funkcję o nazwie, cdktóra jest opakowaniem dla prawdziwych cd. Ten działa dla mnie! Po prostu umieść go w wybranym .bash_profilepliku swojego profilu.

cd () { if [ "$1" = ",," ]; then builtin cd ..; else builtin cd "$@"; fi; }

Lub z komentarzami i ładnym formatowaniem:

cd ()
{
  if [ "$1" = ",," ]; then  # if first argument is ",,"...
    builtin cd ..           # call the builtin cd with ".." instead...
  else
    builtin cd "$@"         # else call builtin cd with original arguments 
  fi
}

EDYTOWAĆ

Dzięki @derobert za wskazanie, że if then elsetutaj jest lepiej niż && ||. Właśnie zrozumiałem ( * facepalm *), że ta implementacja będzie działać tylko wtedy, gdy argumenty inne niż ścieżki (tj. -L -P) Nie są pierwszym argumentem. Więc ostrzegaj, jeśli masz zły nawyk pisania, cd -L ,,to ci nie pomoże. Myślę, że jest to nieistotne, aby postępować poprawnie.

BenjiWiebe
źródło
16
@BenjiWiebe Myślę, że wersja „komentarze i ładne formatowanie” byłaby lepsza w przypadku if-then-else.
zwolnij
Wow ludzie, mnóstwo dobrych pomysłów. Widzę, że używasz funkcji edycji, aby zadbać o potrzebne poprawki. Nie spędzałem dużo czasu testując to. :)
BenjiWiebe
1
Alternatywnie, po prostu nadpisz $1przed wykonaniem wbudowanego:cd () { [ "$1" = ",," ] && set .. ; cd "$@"; }
Toby Speight
1
@TobySpeight set .. "${@:2}"lub stracisz wszystko po pierwszym argumencie.
chepner
8
Również technicznie ..nie musi to być pierwszy argument; cdw bashmoże przybierać różne opcje ( -P, -L, -@, -e).
chepner
29

Aliasy muszą być pierwszym słowem polecenia. Ponadto alias musi zostać zastąpiony słowem, więc nie ma spacji.

Bash Reference Manual: Aliasy

Aliasy umożliwiają zastąpienie łańcucha przez słowo, gdy jest używane jako pierwsze słowo prostego polecenia.

Mógłbyś obu sobie ..i ,,być cd ...

$ alias ..="cd .."
$ alias ,,="cd .."
$ cd /tmp && pwd
/tmp
$ ,, && pwd
/
Steven
źródło
To jest dokładnie to, co robię! : D te dwie kropki / przecinki są znacznie łatwiejsze do cd ..
wpisania
10
+1, to wcale nie jest zły pomysł. Innym sposobem na zrobienie tego .. w Bash jest to, shopt -s autocdże możesz zmienić katalog na dowolny, wpisując jego nazwę. Oczywiście nadal pseudonim dla,,
ilkkachu
Ja też :-)
joeytwiddle
3

Innym sposobem na ..zmianę katalogu jest włączenie autocd funkcji Basha :

shopt -s autocd 

To automatycznie zmieni katalog po wprowadzeniu nazwy jednego:

~$ /tmp
cd /tmp
/tmp$ 

Nadal musisz utworzyć alias, ,,ale można to zrobić za pomocą justalias ,,=..

ilkkachu
źródło
2

Istnieje już aplikacja do tego skryptu: https://github.com/shyiko/commacd (brak powiązań ze Stanleyem Shuyiko).

commacdeksportuje trzy polecenia: ,(do przeskakiwania do przodu), ,,(do tyłu) i ,,,(do tyłu + do przodu):

Wszystkie trzy starają się najpierw dopasować przedrostkiem. Tylko jeśli nie zostaną znalezione żadne wyniki, czy powrócą do dopasowywania podłańcuchowego (rozmytego)

Aby odpowiedzieć na twoje pytanie, skrypt aliasuje przecinki do trzech funkcji, które definiuje:

alias ,=_commacd_forward
alias ,,=_commacd_backward
alias ,,,=_commacd_backward_forward
Doktor Dao
źródło