Lệnh pushd và popd là tính năng tích hợp sẵn của shell Bash giúp bạn "đánh dấu" thư mục để điều hướng nhanh giữa các vị trí trên ổ cứng. Bạn có thể đã cảm thấy terminal là cách điều hướng máy tính nhanh như không tưởng; chỉ trong vài nhấn phím, bạn có thể đến bất cứ đâu trên ổ cứng, bộ nhớ gắn ngoài, hoặc chia sẻ mạng. Nhưng tốc độ đó có thể bị phá vỡ khi bạn thấy mình đi qua lại giữa các thư mục, hoặc khi bạn "mất phương hướng" trong hệ thống file. Đó chính xác là những vấn đề pushd và popd giúp bạn giải quyết.
pushd
Về cơ bản, pushd rất giống cd. Nó đưa bạn từ thư mục này sang thư mục khác. Giả sử bạn có thư mục one, chứa thư mục con two, chứa thư mục con three, và cứ thế. Nếu thư mục làm việc hiện tại là one, bạn có thể chuyển đến two hoặc three hoặc bất cứ đâu bằng lệnh cd:
$ pwd
one
$ cd two/three
$ pwd
three
Bạn có thể làm tương tự với pushd:
$ pwd
one
$ pushd two/three
~/one/two/three ~/one
$ pwd
three
Kết quả cuối cùng của pushd giống cd, nhưng có kết quả trung gian bổ sung: pushd in ra thư mục đích và điểm xuất phát. Đó chính là ngăn xếp thư mục (directory stack), và đó là điều làm pushd độc đáo.
Ngăn xếp (Stacks)
Ngăn xếp, trong thuật ngữ máy tính,指一组元素的集合。在本命令的上下文中,元素是您最近使用 pushd 命令访问的目录。您可以将其视为历史记录或面包屑导航。
您可以使用 pushd 在文件系统中四处移动;每次都会将您之前和新的位置添加到堆栈中:
$ pushd four
~/one/two/three/four ~/one/two/three ~/one
$ pushd five
~/one/two/three/four/five ~/one/two/three/four ~/one/two/three ~/one
Điều hướng trong ngăn xếp
Khi bạn đã xây dựng một ngăn xếp, bạn có thể dùng nó như một tập hợp dấu trang hoặc điểm di chuyển nhanh. Ví dụ, giả sử trong một phiên bạn đang làm nhiều việc trong cấu trúc thư mục ~/one/two/three/four/five của ví dụ này. Bạn biết mình đã đến one gần đây, nhưng không nhớ nó ở đâu trong ngăn xếp pushd. Bạn có thể xem ngăn xếp với đối số +0 (dấu cộng theo sau số không), yêu cầu pushd không chuyển đến thư mục nào trong ngăn xếp, nhưng cũng yêu cầu pushd in ra ngăn xếp hiện tại:
$ pushd +0
~/one/two/three/four ~/one/two/three ~/one ~/one/two/three/four/five
Thay vào đó, bạn có thể xem ngăn xếp bằng lệnh dirs, và thấy số chỉ mục cho mỗi thư mục bằng tùy chọn -v:
$ dirs -v
0 ~/one/two/three/four
1 ~/one/two/three
2 ~/one
3 ~/one/two/three/four/five
Mục đầu tiên trong ngăn xếp là vị trí hiện tại. Bạn có thể xác nhận bằng pwd như bình thường:
$ pwd
~/one/two/three/four
Bắt đầu từ 0 (vị trí hiện tại và mục đầu tiên của ngăn xếp), phần tử thứ hai trong ngăn xếp là ~/one, đích đến mong muốn. Bạn có thể tiến về phía trước trong ngăn xếp dùng tùy chọn +2:
$ pushd +2
~/one ~/one/two/three/four/five ~/one/two/three/four ~/one/two/three
$ pwd
~/one
Thao tác này thay đổi thư mục làm việc thành ~/one và cũng dịch chuyển ngăn xếp để vị trí mới ở đầu.
Bạn cũng có thể lùi lại trong ngăn xếp. Ví dụ, để nhanh chóng đến ~/one/two/three dựa trên ví dụ đầu ra, bạn có thể lùi một bước, nhớ rằng pushd bắt đầu từ 0:
$ pushd -0
~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
Thêm vào ngăn xếp
Bạn có thể tiếp tục điều hướng ngăn xếp theo cách này, và nó sẽ vẫn là danh sách tĩnh các thư mục gần đây truy cập. Nếu bạn muốn thêm thư mục, chỉ cần cung cấp đường dẫn thư mục. Nếu thư mục mới đối với ngăn xếp, nó sẽ được thêm vào danh sách như mong đợi:
$ pushd /tmp
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
Nhưng nếu nó đã tồn tại trong ngăn xếp, nó sẽ được thêm lần thứ hai:
$ pushd ~/one
~/one /tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
Mặc dù ngăn xếp thường dùng như danh sách thư mục bạn muốn truy cập nhanh, nhưng nó thực chất là lịch sử thực sự của nơi bạn đã đi. Nếu bạn không muốn thư mục bị thêm thừa vào ngăn xếp, bạn phải dùng ký hiệu +N và -N.
Xóa thư mục khỏi ngăn xếp
Ngăn xếp của bạn, tất nhiên, không bất biến. Bạn có thể thêm vào bằng pushd hoặc xóa mục bằng popd.
Ví dụ, giả sử bạn vừa dùng pushd thêm ~/one vào ngăn xếp, làm ~/one thành thư mục làm việc hiện tại. Để xóa mục đầu tiên (hoặc "mục số không"):
$ pwd
~/one
$ popd +0
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
$ pwd
~/one
Tất nhiên, bạn có thể xóa bất kỳ mục nào, bắt đầu đếm từ 0:
$ pwd ~/one
$ popd +2
/tmp ~/one/two/three ~/one/two/three/four/five ~/one/two/three/four
$ pwd ~/one
Bạn cũng có thể dùng popd từ cuối ngăn xếp, cũng bắt đầu từ 0. Ví dụ, để xóa thư mục cuối cùng khỏi ngăn xếp:
$ popd -0
/tmp ~/one/two/three ~/one/two/three/four/five
Khi dùng như vậy, popd không thay đổi thư mục làm việc. Nó chỉ thao tác trên ngăn xếp.
Điều hướng với popd
Hành vi mặc định của popd, không có đối số, là xóa mục đầu tiên (số không) khỏi ngăn xếp và làm mục tiếp theo thành thư mục làm việc hiện tại.
Điều này hữu ích nhất như lệnh chuyển đổi nhanh, khi bạn, ví dụ, làm việc ở hai thư mục khác nhau và chỉ cần lướt qua một vị trí khác 잠깐. Bạn không cần nghĩ về ngăn xếp thư mục nếu không cần lịch sử phức tạp:
$ pwd
~/one
$ pushd ~/one/two/three/four/five
$ popd
$ pwd
~/one
Bạn cũng không bắt buộc dùng pushd và popd liên tiếp. Nếu bạn dùng pushd đến vị trí khác, rồi bị phân tâm ba tiếng theo dõi bug hoặc research, bạn sẽ thấy ngăn xếp thư mục vẫn kiên nhẫn chờ đợi (trừ khi bạn kết thúc phiên terminal):
$ pwd ~/one
$ pushd /tmp
$ cd {/etc,/var,/usr}; sleep 2001
[...]
$ popd
$ pwd
~/one
Pushd và popd trong thực tế
Lệnh pushd và popd bất ngờ hữu ích. Khi đã học xong, bạn sẽ tìm ra lý do để dùng chúng tốt, và sẽ quen với khái niệm ngăn xếp thư mục. Làm quen với pushd là điều giúp tôi hiểu git stash, hoàn toàn không liên quan đến pushd nhưng tương tự về mặt khái niệm trừu tượng.
Dùng pushd và popd trong script shell có thể hấp dẫn, nhưng nói chung, tốt nhất nên tránh. Chúng không di động ra ngoài Bash và Zsh, và có thể khó hiểu khi đọc lại script (pushd +3 kém rõ ràng hơn cd $HOME/$DIR/$TMP hoặc tương tự).
Ngoài những cảnh báo trên, nếu bạn là người dùng Bash hoặc Zsh thường xuyên, thì bạn có thể và nên thử pushd và popd.