Tạo cd tự động ls


47

Tôi thấy rằng tôi thường làm như sau:

%> cd bla/bla
%> ls

Tôi muốn nó bất cứ khi nào tôi cdvào một thư mục, nó sẽ tự động làm một ls.

Tôi loay hoay .bashrcmột lúc, nhưng không thể tìm ra cách để nó xảy ra.

Câu trả lời:


51

Bạn có thể làm điều này với một chức năng:

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

&&nghĩa là ' cdđến một thư mục và nếu thành công (ví dụ: thư mục tồn tại), hãy chạy ls'. Sử dụng &&toán tử thì tốt hơn là sử dụng ;toán tử dấu chấm phẩy ở giữa hai lệnh, như với { cd "$@" ; ls; }. Lệnh thứ hai này sẽ chạy lsbất kể có cdhoạt động hay không. Nếu cdthất bại, lssẽ in nội dung của thư mục hiện tại của bạn, điều này sẽ gây nhầm lẫn cho người dùng. Là một thực hành tốt nhất, sử dụng &&và không ;.

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

Nói chung, việc đổi tên một lệnh đã tồn tại là một thực tế xấu, đặc biệt đối với một lệnh thường được gọi là như thế cd. Thay vào đó, tạo một lệnh mới với một tên khác. Nếu bạn ghi đè lên cdvới một chức năng hay bí danh mà cũng được đặt tên cd, điều gì sẽ xảy ra khi bạn nhập một thư mục với 100.000 file? Có nhiều tiện ích sử dụng cdvà chúng có thể bị nhầm lẫn bởi hành vi bất thường này. Nếu bạn sử dụng tài khoản dùng chung (Chẳng hạn như rootkhi bạn đang làm việc với các quản trị viên hệ thống khác), việc thay thế một lệnh hiện có sẽ rất nguy hiểm vì môi trường khác với những gì mọi người mong đợi.


Lệnh đó thực sự thay đổi thư mục? Từ trang man của bash: "Không có cơ chế sử dụng đối số trong văn bản thay thế. Nếu cần đối số, nên sử dụng hàm shell"
enzotib

@enzotib: Vâng, điều này thực sự làm thay đổi thư mục, ít nhất là đối với tôi. Tôi cập nhật câu trả lời của tôi để hiển thị đầu ra của pwd. Không chắc chắn nếu đây là một thực hành tốt nhất, nhưng nó thường được thực hiện. Xem tldp.org/LDP/abs/html/aliases.html để biết một số ví dụ.
Stefan Lasiewski

2
Đầu tiên: nó không hoạt động ở đây. Thứ hai: trong trang đó họ sử dụng các biến, không phải tham số vị trí. Thứ ba: ABS là một nguồn phổ biến của các thực hành xấu.
enzotib

1
Bí danh hoạt động với tôi trên Snow Leopard nhưng không phải trên CentOS5 hoặc CentOS6. Tôi cập nhật câu trả lời của tôi để chỉ sử dụng một chức năng. Không có bí danh.
Stefan Lasiewski

1
Không làm việc cho tôi. Đã thử trả lời @frabjous và nó hoạt động: cd() { builtin cd "$@" && pwd; };- sử dụng vỏ bourne tiêu chuẩn trên macOS (Sierra 10.12.6)
Xoay

39

Tôi có cái này trong .bashrc của tôi và nó hoạt động tốt.

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

Trước đó trong .bashrc của tôi, tôi có: [ -z "$PS1" ] && returnvà mọi thứ sau dòng đó chỉ áp dụng cho các phiên tương tác, vì vậy điều này không ảnh hưởng đến cách cdhành xử trong các tập lệnh.


1
Chính xác thì [ -z "$PS1" ] && returnlàm gì?
cú pháp

2
[ -z "$PS1" ]kiểm tra xem $PS(biến nhắc tương tác) có "độ dài không" (-z). Nếu nó có độ dài bằng 0, điều này có nghĩa là nó chưa được đặt, do đó Bash không được chạy trong chế độ tương tác. Phần && returnthoát ra khỏi nguồn .bashrctại thời điểm này, trong những điều kiện này.
frabjous

1
Một cách khác để kiểm tra tính tương tác là tìm itrong "$-": case "$-" in *i*) ;; *) return ;; esac.
Kusalananda

@Kusalananda & frabjous: Có trường hợp nào nên sử dụng cái này thay cho cái kia không?
Xoay

1
@Sw Xoay PS1Biến có thể không được đặt hoặc trống và shell vẫn có thể tương tác (nhưng không có dấu nhắc). Tôi sẽ kiểm tra $-để đảm bảo.
Kusalananda

13

ngoài chủ đề, vì câu hỏi được gắn thẻ / bash, nhưng vì một số câu hỏi được đóng lại là bản sao của câu hỏi này không đề cập đến bash:

Với zsh:

chpwd() ls

Hàm chpwd () được gọi bởi zsh mỗi khi thư mục hiện tại thay đổi (theo cách của cd, pushd, popd ...). tcsh có một tính năng tương tự và có lẽ là nơi zsh có nó từ đó.


4

Tại sao không thêm bí danh vào tệp .bashrc của bạn?

Cái gì đó như:

alias cdls='cd "$@" && ls'

@don_crissti Một chức năng và bí danh là những thứ khác nhau. Vậy tại sao không?
Lemon Jodka

Đây là cách nhanh nhất và sạch nhất để làm những gì OP yêu cầu. Theo tôi, các hàm nên được sử dụng cho những thứ phức tạp hơn, trong khi tạo các phím tắt cho các lệnh thường được gõ là chính xác những gì bí danh tồn tại.
Ghos3t

1
Tôi gặp một vấn đề lạ với bí danh này, khi tôi sử dụng nó như thế này, cdls projec2, nó sẽ hiển thị tất cả các tệp trong thư mục dự án 2 nhưng không thực sự là cd vào thư mục đó, thay vào đó, nó sẽ vẫn ở trong thư mục gốc.
Ghos3t

Đúng, sử dụng bí danh chỉ đơn giản là liệt kê nội dung trong thư mục đó, nhưng thực tế không phải là cd ở đó.
a3y3

2

Giải pháp chung cho việc tạo bí danh cho lệnh cd là không hoàn hảo vì có các lệnh khác có thể thay đổi thư mục hiện tại của bạn như popd hoặc thậm chí chạy tập lệnh có lệnh cd trong đó.

Tốt hơn là sử dụng hook $ PROMPT_COMMAND để thực thi lệnh trước khi trả về lời nhắc.

Lệnh (một chức năng trong trường hợp của chúng tôi) sẽ chỉ thực hiện ls nếu thư mục đã thay đổi để giảm nhiễu màn hình. Mã cho .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

2

Sao chép cái này:

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

Bây giờ bạn chỉ có thể làm cd đơn giản:

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

1

Trong bash, bạn không thể lặp lại thành bí danh cho hành động yêu cầu tham số. Đối với điều này có chức năng. Vì vậy, đặt trong ~/.bashrcsau đây của bạn

mycd() {
  cd "$1"
  ls
}


Để cho phép một tham số cho lệnh ls, tôi sử dụng hàm mycd {buildin cd $ 1 && ls $ 2}. Bây giờ bạn có thể gọi lệnh, ví dụ: mycd .. -la
Christian Schulzendorff

@ChristianSchulzendorff: tốt hơn để sử dụng dấu ngoặc kép : function mycd { builtin cd "$1" && ls "$2" } .
enzotib

Không hoạt động, tôi chỉ thử nó. Các tập tin trống, nhưng sau khi thêm mã của bạn, không có gì thay đổi.
Đen

0

Đặt mã dưới đây vào .profile và nó hoạt động. Đã thử nghiệm trên hộp 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"

0

Thậm chí tiện dụng hơn - với khả năng quay trở lại trong lịch sử :

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

Khi bạn thay đổi thư mục, một dòng với: Stack: (current_dir) (previous_dir) ...sẽ được hiển thị, sau đó lsxuất ra. Để quay lại lịch sử dirs, chỉ cần bật lệnh này : popd.

Tôi đã thêm elseđể bạn sẽ thấy một lỗi khi cố gắng đi đến một thư mục sai.


nếu bạn chỉ làm cd - nó sẽ đưa bạn đến thư mục cuối cùng mà bạn đã tham gia.
Ian

0

Tôi nghĩ thật tốt khi kích hoạt lscác tùy chọn theo cách này vì cdkhông có tùy chọn nào.

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

Umm ... cdkhông có tùy chọn.
Kusalananda

0

Đây là những gì tôi thấy hữu ích (trên 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
    '
}

Điều này mang lại cho tôi đầu ra bị cắt bằng dấu chấm lửng trong trường hợp có quá nhiều mục trong thư mục đó để giao diện điều khiển sạch sẽ:

$ 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

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

Điều này không thêm gì mà các câu trả lời khác chưa được đề cập.
jasonwryan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.