Faceți cd automat ls (Unix, Bash, Linie De Comandă, Comanda Cd)

RobKohr a intrebat.

Am constatat că fac adesea următoarele:

%> cd bla/bla
%> ls

Aș vrea ca de fiecare dată când cd într-un director, acesta să facă automat un ls.

M-am jucat cu .bashrc pentru o vreme, dar nu am reușit să-mi dau seama cum să fac să se întâmple acest lucru.

12 răspunsuri
Stefan Lasiewski

Poți face acest lucru cu o funcție:

$ cdls() { cd "[email protected]" && ls; }

The && înseamnă ‘cd la un director, iar dacă are succes (de exemplu, directorul există), executați ls‘. Folosind funcția && este mai bună decât utilizarea punct și virgulă ; între cele două comenzi, ca în cazul { cd "[email protected]"; ls; }. Această a doua comandă va rula ls indiferent dacă comanda cd a funcționat sau nu. În cazul în care comanda cd a eșuat, ls va imprima conținutul directorului curent, ceea ce va fi derutant pentru utilizator. Ca o practică optimă, utilizați && și nu ;.

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

În general, este o practică proastă să redenumiți o comandă care există deja, în special pentru o comandă numită în mod obișnuit, cum ar fi cd. În schimb, creați o nouă comandă cu un nume diferit. Dacă suprascrieți cd cu o funcție sau un alias care se numește de asemenea cd, ce s-ar întâmpla dacă ați intra într-un director cu 100 000 de fișiere? Există multe utilitare care utilizează cd, iar acestea ar putea fi derutate de acest comportament neobișnuit. Dacă utilizați un cont partajat (cum ar fi root atunci când lucrați cu alți administratori de sistem), poate fi foarte periculos să înlocuiți o comandă existentă, deoarece mediul este diferit de ceea ce se așteaptă oamenii.

Comentarii

  • Această comandă chiar schimbă directorul? Din pagina de manual a lui bash: „Nu există niciun mecanism de utilizare a argumentelor în textul de înlocuire. Dacă sunt necesare argumente, ar trebui utilizată o funcție de shell” – -.  > Por enzotib.
  • În primul rând: nu funcționează aici. În al doilea rând: în acea pagină se folosesc variabile, nu parametri poziționali. În al treilea rând: ABS este o sursă comună de practici greșite. –  > Por enzotib.
  • Aliasul funcționează pentru mine pe Snow Leopard, dar nu și pe CentOS5 sau CentOS6. Mi-am actualizat răspunsul pentru a folosi doar o funcție. Nu există alias-uri. –  > Por Stefan Lasiewski.
  • Nu funcționează pentru mine. Am încercat răspunsul lui @frabjous și funcționează: cd() { builtin cd "[email protected]" && pwd; }; — folosind shell-ul standard bourne pe macOS (Sierra 10.12.6) –  > Por Swivel.
  • Adică aș prefera să se suprascrie cd pentru cele 100.000 de ori diferite pe care trebuie să le folosesc, mai degrabă decât pentru un singur dosar pe care l-aș putea întâlni potențial cu 100.000 de fișiere. Faptul că trebuie să tastați cdls nu mai are rost și ar putea la fel de bine să facă doar cele două comenzi, dar asta e doar părerea mea –  > Por Emobe.
frabjous

Am acest lucru în .bashrc și funcționează bine.

function cd {
    builtin cd "[email protected]" && ls -F
    }

Mai devreme în .bashrc-ul meu am: [ -z "$PS1" ] && return, și tot ce urmează după această linie se aplică doar sesiunilor interactive, deci nu afectează modul în care cd se comportă în scripturi.

Comentarii

  • Ce anume face [ -z "$PS1" ] && return face? –  > Por syntagma.
  • [ -z "$PS1" ] verifică dacă $PS (variabila de prompt interactiv) este de „lungime zero” (-z). Dacă este de lungime zero, înseamnă că nu a fost setată, deci Bash nu trebuie să ruleze în modul interactiv. Adresa && return partea iese din sursa .bashrc în acest moment, în aceste condiții. –  > Por frabjous.
  • O altă modalitate de a verifica interactivitatea este să căutați i în "$-": case "$-" in *i*) ;; *) return ;; esac. –  > Por Kusalananda.
  • @Kusalananda & frabjous: Există cazuri în care unul ar trebui să fie folosit în locul celuilalt? –  > Por Swivel.
  • @Swivel The PS1 poate fi dezactivată sau goală, iar shell-ul poate fi în continuare interactiv (dar fără prompt). Eu aș verifica $- pentru a fi sigură. –  > Por Kusalananda.
Stéphane Chazelas

off-topic, deoarece întrebarea este etichetată /bash, dar deoarece unele întrebări sunt închise ca duplicate ale acesteia care nu menționează bash:

Cu zsh:

chpwd() ls

Funcția chpwd() este apelată de zsh ori de câte ori se schimbă directorul curent (prin intermediul cd, pushd, popd…). tcsh are o funcție similară și probabil că de acolo a preluat-o zsh.

Kenneth Aar

De ce nu adăugați un alias la fișierul .bashrc?

Ceva de genul:

alias cdls='cd "[email protected]" && ls'

Comentarii

  • @don_crissti O funcție și un alias sunt lucruri diferite. Deci, de ce nu? –  > Por Jodka Lemon.
  • Acesta este cel mai rapid și mai curat mod de a face ceea ce a cerut OP. După părerea mea, funcțiile ar trebui folosite pentru lucruri mai complicate, în timp ce crearea de scurtături pentru comenzi des tastate este exact pentru ce există aliasurile. –  > Por Ghos3t.
  • Am o problemă ciudată cu acest alias, atunci când îl folosesc astfel, cdls projec2, acesta va afișa toate fișierele din folderul project 2, dar nu va face efectiv cd în acel folder, în schimb, va rămâne în folderul original. –  > Por Ghos3t.
  • Da, utilizarea unui alias listează pur și simplu conținutul din acel director, dar nu face de fapt un cd acolo. –  > Por a3y3.
Jack

Soluția obișnuită de a crea un alias pentru comanda cd nu este perfectă, deoarece există alte comenzi care pot schimba directorul curent, cum ar fi popd sau chiar rularea unui script cu comanda cd în el.

Este mai bine să folosiți $PROMPT_COMMAND Bash hook care execută o comandă înainte de a returna un prompt.

Comanda (o funcție în cazul nostru) va executa ls numai dacă directorul s-a schimbat pentru a reduce zgomotul de ecran. Cod pentru .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

Comentarii

  • Am descoperit că setarea unei variabile în LsAfterCd îl va injecta în sesiunea bash curentă. Folosirea unei variabile pentru a păstra directorul permite simplificarea acestui lucru. –  > Por Roger Dahl.
  • Prin „simplificat” vă referiți la „a scăpa de fișierul PrevDir”? –  > Por Jack.
Luciano Andress Martini

Copiați acest lucru:

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

Acum puteți face doar un simplu cd:

cd / 
(files listed)
cd /home 
(files listed)
etc... 

enzotib

În bash nu puteți recurge la aliasuri pentru acțiunea care necesită parametru. Pentru aceasta există funcții. Deci, puneți în ~/.bashrc următoarele

mycd() {
  cd "$1"
  ls
}

Comentarii

  • cd "$1" && ls ar fi mai bine. –  > Por Gilles „SO- nu mai fi rău.
  • Pentru a permite un parametru pentru comanda ls, eu folosesc funcția mycd { builtin cd $1 && ls $2 }. Acum puteți apela comanda, de exemplu, mycd .. -la –  > Por Christian Schulzendorff.
  • @ChristianSchulzendorff: mai bine să folosiți ghilimelele: function mycd { builtin cd "$1" && ls "$2" } . –  > Por enzotib.
  • Nu funcționează, tocmai am încercat. Fișierul era gol, dar după ce am adăugat codul tău, nu s-a schimbat nimic. –  > Por Negru.
Ctrl-C

Chiar mai la îndemână – cu posibilitatea de a a merge înapoi în istorie:

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

Când schimbați directorul unei linii cu: Stack: (current_dir) (previous_dir) ... va fi afișată, apoi ls ieșire. Pentru a vă întoarce în istoricul directoarelor, apăsați această comandă: popd.

Am adăugat else astfel încât să se afișeze o eroare atunci când încercați să accesați un director greșit.

Comentarii

  • dacă faceți cd – vă va duce la ultimul director în care ați fost. –  > Por Ian.
utilizator196161

Puneți codul de mai jos în .profile și funcționează. testat pe o cutie HP-Unix.

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

#SET YOUR ALIAS TO CD
alias cd="cdl"

iBug

Cred că este bine să activați lsîn acest mod, deoarece cd nu ia nici o opțiune.

cdls() {
  cd ${$#} && ls ${@:0:$#-1}
}

Comentarii

  • Umm… cd acceptă opțiuni. –  > Por Kusalananda.
Superlexx

Iată ce găsesc eu util (pe Debian 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
    '
}

Aceasta îmi oferă o ieșire trunchiată cu o elipsă în cazul în care există prea multe elemente în acel director, astfel încât consola să rămână curată:

$ 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

joek
alias cd='builtin cd $1 && ls -l && builtin cd $1'

Comentarii

  • Acest lucru nu adaugă nimic pe care celelalte răspunsuri nu l-au acoperit deja. –  > Por jasonwryan.