Utwórz cd automatycznie ls

46

Uważam, że często wykonuję następujące czynności:

%> cd bla/bla
%> ls

Chciałbym, aby za każdym razem, gdy wchodzę cddo katalogu, robi to automatycznie ls.

.bashrcPrzez chwilę bawiłem się ze mną , ale nie mogłem wymyślić, jak to zrobić.

RobKohr
źródło

Odpowiedzi:

50

Możesz to zrobić za pomocą funkcji:

$ cdls() { cd "$@" && ls; }

Te &&środki „ cddo katalogu, a jeśli się powiedzie (na przykład katalog istnieje), Run ls”. Użycie &&operatora jest lepsze niż użycie ;operatora średnika między dwiema komendami, jak w przypadku { cd "$@" ; ls; }. To drugie polecenie będzie działać lsniezależnie od tego, czy cdzadziałało, czy nie. Jeśli się cdnie powiedzie, lswydrukuje zawartość twojego bieżącego katalogu, co będzie mylące dla użytkownika. Jako najlepszą praktykę używaj &&i nie ;.

$ cdls /var/log
CDIS.custom     fsck_hfs.log    monthly.out     system.log
$ pwd
/var/log

Ogólnie rzecz biorąc, złą praktyką jest zmiana nazwy polecenia, które już istnieje, szczególnie w przypadku często nazywanego polecenia, takiego jak cd. Zamiast tego utwórz nowe polecenie o innej nazwie. Jeśli zastąpisz cdfunkcję lub alias o nazwie cd, co się stanie, gdy wejdziesz do katalogu zawierającego 100 000 plików? Istnieje wiele narzędzi, z których można korzystać cdi mogą się mylić z powodu tego niezwykłego zachowania. Jeśli korzystasz ze wspólnego konta (na przykład rootpodczas pracy z innymi administratorami systemu), zastąpienie istniejącego polecenia może być bardzo niebezpieczne, ponieważ środowisko różni się od oczekiwań ludzi.

Stefan Lasiewski
źródło
To polecenie naprawdę zmienia katalog? Ze strony podręcznika bash: „Nie ma mechanizmu używania argumentów w tekście zastępczym. Jeśli argumenty są potrzebne, należy użyć funkcji powłoki”
enzotib
@enzotib: Tak, to naprawdę zmienia katalog, przynajmniej dla mnie. Zaktualizowałem swoją odpowiedź, aby pokazać wynik pwd. Nie jestem pewien, czy jest to najlepsza praktyka, ale często się to odbywa. Zobacz przykłady tldp.org/LDP/abs/html/aliases.html .
Stefan Lasiewski
2
Po pierwsze: tutaj nie działa. Po drugie: na tej stronie używają zmiennych, a nie parametrów pozycyjnych. Po trzecie: ABS jest częstym źródłem złych praktyk.
enzotib
1
Alias ​​działa dla mnie na Snow Leopard, ale nie na CentOS5 lub CentOS6. Zaktualizowałem swoją odpowiedź, aby używać tylko funkcji. Bez aliasów.
Stefan Lasiewski
1
Nie działa dla mnie. Wypróbowałem @frabjous odpowiedź i działa: cd() { builtin cd "$@" && pwd; };- używając standardowej powłoki Bourne'a w systemie macOS (Sierra 10.12.6)
Obróć
39

Mam to w moim .bashrc i działa dobrze.

function cd {
    builtin cd "$@" && ls -F
    }

Wcześniej w moim .bashrc mam: [ -z "$PS1" ] && returni wszystko po tym wierszu dotyczy tylko sesji interaktywnych, więc nie wpływa to na cdzachowanie skryptów.

frabjous
źródło
1
Co dokładnie robi [ -z "$PS1" ] && return?
syntagma
2
[ -z "$PS1" ]sprawdza, czy $PS(interaktywna zmienna zachęty) ma „zerową długość” (-z). Jeśli ma zerową długość, oznacza to, że nie została ustawiona, więc Bash nie może działać w trybie interaktywnym. && returnCzęść wychodzi z zaopatrywaniu .bashrcw tym momencie, w tych warunkach.
frabjous
1
Innym sposobem sprawdzenia interaktywność jest szukanie iw "$-": case "$-" in *i*) ;; *) return ;; esac.
Kusalananda
@Kusalananda & frabjous: Czy istnieją przypadki, w których należy użyć jednego zamiast drugiego?
Obrót
1
@ Swivel PS1Zmienna może być rozbrojona lub pusta, a powłoka może być nadal interaktywna (ale bez monitu). Sprawdziłbym, $-żeby się upewnić.
Kusalananda
13

nie na temat, ponieważ pytanie jest oznaczone / bash, ale ponieważ niektóre pytania są zamknięte jako duplikat tego, który nie wspomina o bash:

Z zsh:

chpwd() ls

Funkcja chpwd () jest wywoływana przez zsh za każdym razem, gdy zmienia się bieżący katalog (za pomocą cd, pushd, popd ...). tcsh ma podobną funkcję i prawdopodobnie jest tam, skąd Zsh go otrzymał.

Stéphane Chazelas
źródło
4

Dlaczego nie dodać aliasu do pliku .bashrc?

Coś jak:

alias cdls='cd "$@" && ls'
Kenneth Aar
źródło
@don_crissti Funtion i alias to różne rzeczy. Dlaczego nie
Jodka Lemon
Jest to najszybszy i najczystszy sposób robienia tego, o co poprosił PO. Moim zdaniem, funkcji należy używać do bardziej skomplikowanych rzeczy, podczas gdy tworzenie skrótów do często wpisywanych poleceń jest dokładnie tym, dla czego istnieją aliasy.
Ghos3t
Mam dziwny problem z tym aliasem, kiedy użyję go w ten sposób, cdls projec2, pokaże wszystkie pliki w folderze projektu 2, ale nie będzie w rzeczywistości cd do tego folderu, zamiast tego pozostanie w oryginalnym folderze.
Ghos3t
2

Powszechne rozwiązanie tworzenia aliasu dla polecenia cd nie jest idealne, ponieważ istnieją inne polecenia, które mogą zmienić bieżący katalog, np. Popd, a nawet uruchomić skrypt z poleceniem cd.

Lepiej użyć $ PROMPT_COMMAND haka Bash, który wykonuje polecenie przed zwróceniem monitu.

Polecenie (w naszym przypadku funkcja) wykona ls tylko wtedy, gdy katalog został zmieniony w celu zmniejszenia szumów na ekranie. Kod .bashrc:

    #each console has its own file to save PWD
    PrevDir=$(tty) 
    PrevDir=/tmp/prev-dir${PrevDir////-}
    #don't ls when shell launched
    echo $PWD > $PrevDir
    LsAfterCd() {
        [[ "$(< $PrevDir)" == "$PWD" ]] && return 0

        ll --color=always | sed 1d

        echo $PWD > $PrevDir
    }
    PROMPT_COMMAND=LsAfterCd
Jacek
źródło
2

Skopiuj to:

altercd(){ cd(){ unset -f cd ; cd $*; ls ; altercd; } } ; altercd 

Teraz możesz po prostu zrobić prostą płytę CD:

cd / 
(files listed)
cd /home 
(files listed)
etc... 
Luciano Andress Martini
źródło
1

W bash nie można powracać do aliasów dla akcji wymagających parametru. Do tego są funkcje. Wpisz więc ~/.bashrcnastępujące informacje

mycd() {
  cd "$1"
  ls
}
enzotib
źródło
4
cd "$1" && lsbyłoby lepiej.
Gilles „SO- przestań być zły”
Aby zezwolić na parametr dla polecenia ls, używam funkcji mycd {wbudowany cd $ 1 && ls $ 2}. Teraz możesz wywołać polecenie np. Mycd .. -la
Christian Schulzendorff,
@ChristianSchulzendorff: lepiej użyć cudzysłowu: function mycd { builtin cd "$1" && ls "$2" } .
enzotib
Nie działa, właśnie go wypróbowałem. Plik był pusty, ale po dodaniu kodu nic się nie zmieniło.
Czarny
0

Umieść poniższy kod w .profile i działa. Testowany na komputerze HP-Unix.

cdl()
{
if [ "$#" = 0 ]; then
cd ~ && ls -ltr
elif [ -d "$@" ]; then
cd "$@" && ls -ltr
else
echo "$@" directory not found!!!
fi
}

#SET YOUR ALIAS TO CD
alias cd="cdl"
użytkownik196161
źródło
0

Jeszcze bardziej przydatny - z możliwością powrotu do historii :

function cd() {
    if [ -d "$@" ]; then
        echo -n "Stack: "
        pushd "$@"
        ls
    else
        builtin cd "$@"
    fi
}
function popd() {
    builtin popd "$@" && ls
}

Po zmianie katalogu pojawi się wiersz z Stack: (current_dir) (previous_dir) ...:, a następnie lswyjście. Aby wrócić katalogów historia po prostu pop polecenia: popd.

Dodałem, elsewięc zobaczysz błąd podczas próby przejścia do niewłaściwego katalogu.

Ctrl + C
źródło
jeśli tylko nagrasz płytę CD - przeniesie Cię do ostatniego katalogu, w którym byłeś.
Ian
0

Myślę, że dobrze jest włączyć lsopcje w ten sposób, ponieważ cdnie ma opcji.

cdls() {
  cd ${$#} && ls ${@:0:$#-1}
}
iBug
źródło
Umm ... cdbierze opcje.
Kusalananda
0

Oto, co uważam za przydatne (w Debianie 9):

c() {
    cd "${@}" \
    && ls --color=always -C \
    | sed '
        # on line 5, print the line,
        5 {
            # append an ellipsis
            a[...]
            # and quit
            q
        }
        # print lines 1-4 verbatim
    '
}

Daje mi to obcięte dane wyjściowe z wielokropkiem na wypadek, gdyby w tym katalogu było zbyt wiele elementów, aby konsola pozostała czysta:

$ c data/git/buildroot/package/
4th                              lua-markdown
a10disp                          lua-messagepack
acl                              lua-msgpack-native
acpica                           luaossl
acpid                            lua-periphery
[...]
$ ls -1 | wc --lines
1977
Superlexx
źródło
-1
alias cd='builtin cd $1 && ls -l && builtin cd $1'
joek
źródło
Nie dodaje to niczego, czego inne odpowiedzi jeszcze nie obejmowały.
jasonwryan 17.07.16