Sự khác biệt giữa các lệnh dựng sẵn cd và cd là gì?


17

Tôi đã gặp một lệnh Linux , builtin cd.

Sự khác biệt giữa các lệnh builtin cdvà là cdgì?

Trên thực tế, tôi đã thực hiện một số nghiên cứu về sự khác biệt, nhưng tôi không thể tìm thấy một lời giải thích đáng chú ý và quan trọng về điều này.



Câu trả lời:


41

Các cdlệnh là một built-in, vì vậy thường builtin cdsẽ làm điều tương tự như cd. Nhưng có một sự khác biệt nếu cdđược xác định lại là hàm hoặc bí danh, trong trường hợp đó cdsẽ gọi hàm / bí danh nhưng builtin cdvẫn sẽ thay đổi thư mục (nói cách khác, sẽ giữ cho có thể truy cập được tích hợp ngay cả khi bị chặn bởi hàm.)

Ví dụ:

user:~$ cd () { echo "I won't let you change directories"; }
user:~$ cd mysubdir
I won't let you change directories
user:~$ builtin cd mysubdir
user:~/mysubdir$ unset -f cd  # undefine function

Hoặc với một bí danh:

user:~$ alias cd='echo Trying to cd to'
user:~$ cd mysubdir
Trying to cd to mysubdir
user:~$ builtin cd mysubdir
user:~/mysubdir$ unalias cd  # undefine alias

Sử dụng builtincũng là một cách tốt để xác định cdhàm thực hiện một cái gì đó thay đổi thư mục (vì việc gọi cdtừ nó sẽ tiếp tục gọi lại hàm đó trong một đệ quy vô tận.)

Ví dụ:

user:~ $ cd () { echo "Changing directory to ${1-home}"; builtin cd "$@"; }
user:~ $ cd mysubdir
Changing directory to mysubdir
user:~/mysubdir $ cd
Changing directory to home
user:~ $ unset -f cd  # undefine function

5
+1 Các ví dụ đặc biệt minh họa ở đây.
Tashus

2
Trong trường hợp bí danh, có sự khác biệt nào giữa builtin cd mysubdir\cd mysubdirkhông?
gerrit

2
@gerrit Chỉ khi có một hàm được đặt tên cd, trong trường hợp đó \cdsẽ bỏ qua bí danh và chạy hàm. Xem stackoverflow.com/a/16506263/4518341
wjandrea

15

Trong hầu hết các trường hợp, không có sự khác biệt (nhưng xem bên dưới). Các cdlệnh là một built-in lệnh trong tất cả vỏ. Nó cần được tích hợp sẵn 1 vì một lệnh bên ngoài không thể thay đổi môi trường của trình gọi và việc thay đổi thư mục làm việc sẽ tạo ra một sự thay đổi trong môi trường của nó.

Các bashlệnh builtinlực lượng vỏ để sử dụng được xây dựng trong phiên bản của một lệnh, mặc dù có thể có một chức năng vỏ, bí danh, hoặc lệnh bên ngoài sẵn có cùng tên.

Trong trường hợp có được ví dụ như một chức năng vỏ với tên cd, sau đó builtin cdsẽ không gọi đó. Việc sử dụng builtin cdbỏ qua mọi chức năng bị quá tải có thể được thêm vào thông qua chức năng shell hoặc bí danh của người dùng.

Thí dụ:

Các cdbuilt-in lệnh có thể bị quá tải bởi một hàm cập nhật kịp thời:

cd() {
    builtin cd "$@" && PS1=$(__update_prompt)
}

trong đó __update_promptmột số hàm do người dùng cung cấp khác tạo ra một chuỗi.

Hàm builtin cdtrong sẽ không gọi hàm đệ quy. Sử dụng builtin cdtrong trình bao có chức năng này đang hoạt động, ngoài ra sẽ không gọi hàm.


1 Có các Unice với một cdlệnh bên ngoài (macOS, và, tôi tin rằng, Solaris). Mục đích của lệnh đó, không thể thay đổi thư mục làm việc cho shell, có thể để đáp ứng tiêu chuẩn POSIX, liệt kê cdlà một trong những tiện ích bên ngoài nên có ( cdkhông phải là một trong những "tiện ích dựng sẵn đặc biệt") . Nó cũng có thể phục vụ như một thử nghiệm để xem liệu thay đổi thư mục công việc sang một thư mục nhất định có khả thi hay không .


FWIW, MacOS cũng sẽ thuộc danh mục HĐH với cdlệnh bên ngoài .
yoann

@yoann Quả thực là như vậy.
Kusalananda

Cảm ơn bạn - bạn đã làm cho ngày của tôi với đỉnh cao, được nghiên cứu kỹ ,, nhà sư phạm chú thích.
james

hầu hết các shell - đó là một chương trình bên ngoài cho execlineb, nhưng sau đó cd sẽ thực thi các đối số còn lại của nó
Grump
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.