Có cd. có dùng không?


102

Một trong những hướng dẫn tôi đã theo dõi ngắn gọn tuyên bố rằng cd .không có sử dụng. Khi cố gắng sao chép vấn đề được hiển thị bởi OP trong đệ quy liên kết tượng trưng - điều gì làm cho nó thiết lập lại bản thân? , Tôi cũng đã thử cd ., cho thấy hiệu ứng tương tự mà OP mô tả ( $PWDbiến tăng trưởng ), có thể chống lại cd -P.

Điều này khiến tôi tự hỏi, có trường hợp nào người ta thực sự muốn sử dụng cd . không?


20
Tôi có một .zshrc tùy chỉnh chạy các kiểm tra khác nhau trên thư mục khi chuyển đổi thư mục, ví dụ một trong những kiểm tra là tự động kích hoạt / hủy kích hoạt một virtualenv phù hợp khi di chuyển các thư mục. Thỉnh thoảng, tôi có thể bắt đầu một trình bao mới hoặc bất cứ điều gì, và những kiểm tra đó không chạy và tôi thường sử dụng cd .để kích hoạt các kiểm tra đó vì nó ngắn và đơn giản. Mặc dù tôi nghĩ rằng bạn dự định câu hỏi là cho một môi trường vani.
Nói dối Ryan

29
Bên cạnh hiệu ứng (hiển nhiên) trên $PWD, cd .cũng thay đổi $OLDPWDthư mục hiện tại. Tôi (hiện tại) không biết tại sao điều này có thể hữu ích, nhưng vì lợi ích của sự hoàn chỉnh,
Andreas Wiese

5
Tôi không nghĩ rằng tôi đã từng cần cd ., mặc dù nhìn thấy câu trả lời bên dưới, tôi có thể trong tương lai, nhưng đôi pushd .khi tôi đã sử dụng khi tôi muốn có thể popdquay lại thư mục này sau. ví dụ như khi chạy một kịch bản xây dựng mà không configure, cd output...make, và khi nó được thực hiện, tôi sẽ muốn quay trở lại vào thư mục gốc. Thay vì duy trì bản sao của bản dựng của tôi khác với những gì mọi người mong đợi, tôi chỉ chạy nó pushd .; ./BuildScriptName.sh; popdvà điều này cũng cho tôi sự tự do không popdđôi khi, và sau popdđó thay vào đó.
3D1T0R

5
Tất nhiên không đề cập đến điều đó '.' và '..' không được triển khai trong chính lệnh cd, vì vậy không ai bắt đầu thực hiện tính năng cụ thể đó, đó chỉ là sự kết hợp của những thứ không phục vụ mục đích thực sự.
David S

1
@ruakh Không, các chương trình bên ngoài sẽ không ảnh hưởng đến môi trường thực thi shell. Phần lớn là tuân thủ POSIX, yêu cầu một số tiện ích tồn tại bên ngoài lớp vỏ và đánh giá trạng thái thoát của các lệnh bên ngoài. Bạn có thể đọc về mục đích của /bin/cdđây unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Câu trả lời:


158

Tôi nghĩ rằng điều này là lật đổ vấn đề. cd .có thể không phải là thứ mà người ta sẽ tự chạy theo cách thông thường, nhưng nó chắc chắn là thứ có thể xảy ra khi thực hiện theo chương trình (nghĩ về bất kỳ tình huống nào bạn có thể cdđến thư mục chứa tệp, có đường dẫn được cung cấp bởi người dùng ). Do đó, nó không phải có một số cách sử dụng cụ thể: miễn là nó đáp ứng các ngữ nghĩa thông thường của cd <some-path>nó, nó rất hữu ích.


12
Đồng ý, .nên được coi là một đường dẫn hợp lệ được chỉ định bởi cdcú pháp tốt.
Sergiy Kolodyazhnyy

18
Bạn có thể thêm ví dụ sau: Vòng lặp like IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). Trong quá trình của nó, find tạo ra .như là đường dẫn, để lệnh cd "$Dir"mở rộng đến cd .. Vì vậy, trong các kịch bản, nó là hoàn toàn hữu ích.
rexkogitans

5
Ví dụ, một tập lệnh thực sự chạy cd ${path_to_directory}, nhưng tại một số điểm, nó chỉ ra thư mục là thư mục hiện tại, và path_to_directory = .vì vậy bạn sẽ cần cd .phải làm việc chỉ trong trường hợp.
Demis

4
Nói cách khác, tiện ích của nó nằm ở chỗ nó làm cho mã bổ sung ( ifkiểm tra và elsemệnh đề, bất kỳ loại vỏ đặc biệt nào) không cần thiết.
jpmc26

2
Vì vậy, nó hữu ích theo nghĩa x + 0 hoặc x * 1 là hữu ích - thao tác cụ thể không hữu ích cho mỗi se, nhưng điều đó có nghĩa là bạn có thể xử lý 0 và 1 giống như bất kỳ giá trị nào khác, mà không phải coi chúng là một trường hợp đặc biệt
dùng32929

127

Đường dẫn của thư mục có thể đã thay đổi kể từ khi lệnh cuối cùng được thực thi và nếu không có cd .bash và ksh93 shell sẽ dựa vào thư mục làm việc logic được mô tả trong bài đăng được liên kết trong câu hỏi, do đó, việc gọi cd .ra vấn đề này getcwd()sẽ tạo ra vỏ sò sẽ đảm bảo đường dẫn hiện tại vẫn còn hiệu lực.

Các bước để sinh sản trong bash:

  1. Trong một vấn đề tab thiết bị đầu cuối mkdir ./dir_no_1; cd ./dir_no_1
  2. Trong một vấn đề tab thiết bị đầu cuối khác mv dir_no_1 dir_no_2
  3. Trong vấn đề đầu cuối tab đầu tiên echo $PWDpwd. Lưu ý rằng thư mục đã được đổi tên bên ngoài; môi trường của shell chưa được cập nhật.
  4. Vấn đề cd .; pwd; echo $PWD. Thông báo giá trị đã được cập nhật.

ksh93, tuy nhiên, không cập nhật thông tin môi trường, vì vậy cd .trong ksh93 trên thực tế có thể là vô dụng. Trong /bin/dashUbuntu và các hệ thống dựa trên Debian khác, cd .trả về dash: 3: cd: can't cd to .lỗi, tuy nhiên cd -P .hoạt động (không giống như trong ksh93).


22
Những điều cần biết: Tôi sẽ thêm nó vào danh sách những thông tin vô dụng của tôi. ^^)
jayooin

12
@jayooin Vui mừng tôi có thể đóng góp vào danh sách này;)
Sergiy Kolodyazhnyy

8
Tôi nghĩ bạn có thể làm mv ../dir_no_1 ../dir_no_2trong cùng một thiết bị đầu cuối / bash.
ctrl-alt-delor

3
@ ctrl-alt-delor Xác nhận, hoạt động :)
Sergiy Kolodyazhnyy

1
@ymbirtt Trong hầu hết các shell, pwdtrên thực tế, được tích hợp sẵn, tuy nhiên việc gọi /bin/pwdkhông có tác dụng đối với môi trường của shell - nói chung các tiện ích bên ngoài không ảnh hưởng đến môi trường shell. Lý do tại sao /bin/cd/bin/pwdtồn tại là vì sự phù hợp POSIX, trong số những thứ khác. Có một cuộc thảo luận tốt về cd bên ngoài, một số trong đó có thể áp dụng cho /bin/pwdcả
Sergiy Kolodyazhnyy

55

Một trường hợp sử dụng khác cd .là khi thư mục bạn hiện đang bị xóa và sau đó được tạo lại. Cân nhắc thử những điều sau -

  1. Tạo một thư mục temp
  2. cd temp và sau đó làm một ls
  3. Mở một thiết bị đầu cuối khác và xóa và sau đó tạo lại thư mục đó temp
  4. Quay lại từ thiết bị đầu cuối đầu tiên, hãy thử làm một ls. Điều này sẽ dẫn đến một lỗi -ls: cannot open directory .: Stale file handle
  5. cd . và sau đó làm một ls hoạt động tốt

3
Điều này không phải lúc nào cũng hoạt động. Ví dụ, trong dấu gạch ngang, bạn sẽ nhận được: cd: can't cd to .Bây giờ tôi nhìn vào nó, điều này đã được đề cập trong câu trả lời của Sergiy (di chuyển, xóa / tái tạo - về cơ bản là giống nhau: thư mục bạn đang ở không còn như trong bản gốc đường dẫn)
Olorin

12
Tôi sử dụng điều này rất nhiều thử nghiệm triển khai từ xa. Thư mục tôi đang ở sẽ bị xóa sau đó được tạo lại bởi một số tự động hóa và tôi sẽ cần phải phát hành cd .để chuyển sang thư mục mới có cùng tên.
HP Williams

2
Tôi sử dụng cd .tất cả thời gian khi tôi có một shell có thư mục làm việc hiện tại được gắn với sshfs nhưng phiên ssh đã bị đóng và mở lại.
jamesdlin

4
Trong trường hợp như vậy tôi làm "cd $ PWD". Các biến thể khác có thể hoạt động, nhưng biến thể này thể hiện rõ ràng ý định: trích xuất cái được cho là đường dẫn hiện tại của tôi (tức là đọc nội dung của PWDbiến môi trường), sau đó chuyển hệ thống phân cấp tệp từ gốc, xuống thư mục có thể truy cập qua đường dẫn đó, cho dù nó thực sự là cùng một thư mục hay không. Điều này phù hợp chính xác trường hợp sử dụng trong câu trả lời này.
Stéphane Gourichon

3
Tôi thực sự ngạc nhiên, bị sốc, thậm chí nó cd .hoạt động khi thư mục đã được hủy liên kết và một thư mục mới, khác được tạo ở cùng một đường dẫn hệ thống tệp. Thư mục làm việc hiện tại đã không được liên kết và có lẽ là một phần của điều đó, nó không còn có .hoặc một ..mục, và ngay cả khi nó đã làm, .mục nhập nên tiếp tục trỏ đến chính nó. Dường như shell hoặc kernel đang thực thi lệnh cd dựa trên tên đường dẫn thư mục thay vì chỉ đơn giản là truy cập vào .mục. Bất cứ ai cũng có thể xác nhận hành vi đó?
Adrian Pronk

36

Bạn có thể xóa $OLDPWDnhanh chóng cd ., nếu có trường hợp bạn không muốn nó chỉ ra bất cứ nơi nào "thú vị". Nó cũng sẽ ảnh hưởng cd -.


16

Về mặt lập trình, nó rất hữu ích khi không hoạt động. Hãy xem xét một đường dẫn được cung cấp từ đầu vào bên ngoài.

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

Với một đường dẫn như "fred.txt", thư mục sẽ trở thành ., dẫn đếncd .


1
Thật hữu ích khi nó không gây ra lỗi nếu bạn đã ở trong thư mục mà bạn đang điều hướng, nhưng tôi sẽ không nói rằng nó hữu ích như là một công cụ không hoạt động.
Thuyền trưởng Man

2
@CaptainMan không đưa ra lỗi nếu bạn đã có trong thư mục (một cách hiệu quả) là không có. Các dirnamelệnh tạo ra .khi cần thiết nhằm tránh mã bẻ rằng hy vọng để có thể chia một con đường.
roaima

15

Điều này là phổ biến nếu bạn phải làm việc với cáp USB xấu. Sau khi một thiết bị bị ngắt kết nối và kết nối lại, và tự động kết nối với cùng một thư mục, bạn phải sử dụng cd .để thiết bị hoạt động trở lại.


1
Điều đó không phụ thuộc vào loại thiết bị nào, cách truy cập, hệ thống tập tin, hệ điều hành, & c?
chơi

Hệ điều hành, có thể. Không chắc hệ thống tập tin có liên quan, miễn là hạt nhân có thể tìm thấy đường của nó để ngắt kết nối nó trong khi nó đang được sử dụng. Trong mọi trường hợp, lệnh có sử dụng trong tình huống chính xác.
dùng23013

11

Lưu ý rằng "." cách thích hợp để chỉ định tên của tệp được mở dưới dạng thư mục làm việc hiện tại của bất kỳ quy trình nào (bao gồm cả quy trình shell) và "." luôn luôn là một tên hợp lệ của một tập tin trong bất kỳ và tất cả các thư mục, bao gồm cả thư mục làm việc hiện tại. Tên .có thể không phải là tên hợp lệ cho một tệp cho một phiên bản đã cho của một quy trình nếu, giả sử, thư mục làm việc hiện tại nằm bên dưới đã bị xóa (hoặc biến thành "xấu", ví dụ: xử lý NFS cũ), nhưng đó là tên hợp lệ của một tập tin được đảm bảo tồn tại trong mọi thư mục hợp lệ.

Vì vậy, . phải là một đối số hợp lệ cho bất kỳ lệnh nào chấp nhận tên của một thư mục và do đó trong shell tiêu chuẩn cd .phải là một lệnh hợp lệ.

cd .hữu ích hay không phụ thuộc vào việc thực hiện shell. Như đã đề cập, nó có thể hữu ích nếu shell đặt lại ý tưởng bên trong của nó về tên đường dẫn đầy đủ của thư mục làm việc hiện tại sau khi gọi lệnh chdirhệ thống cơ bản , ví dụ như nếu thư mục bên dưới (hoặc một số cha mẹ của nó) đã được đổi tên.

Ít nhất một số shell mà tôi biết ( /bin/shtrên FreeBSD và NetBSD) sẽ chuyển đổi cd ""thành cd ., có thể được mô tả là một tính năng để hỗ trợ sử dụng lập trình trong tập lệnh shell trong đó một biến có thể được sử dụng làm tham số (nghĩa là chuyển đổi thay thế biến rỗng thành " không làm gì cả "kết quả), mặc dù lịch sử cam kết FreeBSD nói rằng sự thay đổi là trực tiếp do thêm hỗ trợ POSIX để ngăn chặn sự cố từ chdir("")đó, mà các nhiệm vụ POSIX phải thất bại.

Một số shell khác sẽ thay thế .bằng bất cứ thứ gì chúng đã lưu trữ dưới dạng tên đường dẫn đủ điều kiện vào thư mục làm việc hiện tại của chúng, và do đó, chúng có thể cho phép hành vi được đề cập trong câu trả lời của Sahil Agarwal .


4

Tôi đã sử dụng lệnh này ngay hôm nay khi tôi khởi động lại nhánh mà tôi đang làm việc trong Git, từ trong một thư mục lần đầu tiên được tạo trên cùng nhánh đó. Cuộc nổi loạn đã diễn ra tốt đẹp nhưng sau đó, git statusđã gây ra lỗi. Sau khi cd .mọi thứ đều bình thường.

(Tôi đang làm việc trong MobaXterm trên Windows, tình cờ. Chỉ trong trường hợp bạn đang cố gắng tái tạo điều này. Nó có thể không xảy ra trên các hệ thống khác.)


Tôi cũng đã sử dụng lệnh này trong các thư mục được làm mới bởi một quy trình tự động chuyển sang một thư mục cũ và thay thế nó bằng một thư mục mới (vì vậy nó càng gần với nguyên tử càng tốt). Không phải là một tình huống phổ biến nhưng cd .chính xác là những gì cần thiết.


Sau khi đọc câu trả lời tuyệt vời này từ Stephane Chazelas:

Bây giờ tôi hiểu rằng các trường hợp sử dụng của tôi ở trên chỉ hoạt động vì tôi đang sử dụng bash, trong đó cd .tương đương với cd "$PWD". Tôi rất khuyên bạn nên đọc câu trả lời liên kết.


1

Tôi sử dụng cd .để chạy lại những thứ tôi đã quá tải cdthông qua một bashchức năng.

Từ tôi ~/.bashrc:

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}

0

EDIT: Điều này đã được đề xuất bởi Sahil trước đây.

Điều này rất hữu ích nếu bạn đang ở trong một thư mục đã bị xóa và được tạo lại bởi một quy trình khác. Ví dụ: giả sử hai phiên cuối $1$2:

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

Tôi không chắc liệu chính xác (OS, SHELL, ...?) Nguyên nhân gốc rễ của hành vi này là ở đâu.


Điều này đã được đề cập bởi các câu trả lời khác.
Kusalananda

-8

Không, nó không có ý nghĩa. Không phải trong kịch bản, nó chỉ không làm gì cả.


2
Tùy thuộc vào shell, nó sẽ thiết lập lại $PWDvà nó có thể gọi các hàm shell khác nếu người dùng đã cung cấp cdchức năng hoặc bí danh của riêng họ để quá tải tích hợp sẵn cd. Nó cũng sẽ xác minh rằng thư mục hiện tại vẫn còn hiệu lực và việc sử dụng hiện tại có quyền ở đó.
Kusalananda

1) tất nhiên chúng ta không nói về các bí danh tùy chỉnh có thể có của "cd" nhưng bản dựng tiêu chuẩn 2) làm thế nào việc sử dụng hiện tại có thể ở đó nếu nó không có sự cho phép? Để đơn giản, tôi chỉ nói rằng trong thế giới thực, không có lý do gì để sử dụng nó theo ý kiến ​​của tôi.
Federico

1
1) Chúng ta không? 2) Thế giới thực không đơn giản và Unix là một hệ điều hành nhiều người dùng. Người dùng có thể thay đổi quyền trên các thư mục và nếu tập lệnh hoặc vỏ tương tác của người dùng khác, tình cờ có thư mục đó (hoặc thư mục con của nó) làm thư mục làm việc, cd .sẽ khiếu nại.
Kusalananda

4
Federico, theo các quy tắc của trang web và quy tắc cá nhân của riêng tôi, tôi nên đánh giá thấp câu trả lời của bạn. Tuy nhiên, bạn là người mới. Chào mừng bạn Vui lòng xem lại một số câu trả lời khác . Sau đó, nếu bạn nghĩ rằng câu trả lời của bạn là sai, xin vui lòng xóa nó. Hãy tận hưởng việc đưa ra câu trả lời khác cho câu hỏi này và những người khác.
daveloyall

2
Đặc biệt là trong kịch bản, đôi khi "không làm gì" chính xác là những gì cần thiết.
Matthew Najmon
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.