Sự lựa chọn tiêu đề của câu hỏi của bạn là một chút bối rối.
pushd
/ popd
, một csh
tính năng được sao chép bởi bash
và zsh
, là một cách để quản lý một chồng các thư mục đã nhớ.
pushd /some/dir
đẩy thư mục làm việc hiện tại lên một ngăn xếp, và sau đó thay đổi thư mục làm việc hiện tại (và sau đó in /some/dir
theo nội dung của ngăn xếp đó (được phân tách bằng dấu cách).
popd
in nội dung của ngăn xếp (một lần nữa, khoảng cách được phân tách) và sau đó thay đổi thành phần tử trên cùng của ngăn xếp và bật nó từ ngăn xếp.
(cũng hãy cẩn thận rằng một số thư mục sẽ được trình bày ở đó với ký hiệu ~/x
hoặc ~user/x
ký hiệu của chúng).
Vì vậy, nếu ngăn xếp hiện có /a
và /b
, thư mục hiện tại đang /here
và bạn đang chạy:
pushd /tmp/whatever
popd
pushd
sẽ in /tmp/whatever /here /a /b
và popd
sẽ xuất /here /a /b
, không /tmp/whatever
. Điều đó độc lập với việc sử dụng thay thế lệnh hay không. popd
không thể được sử dụng để có được đường dẫn của thư mục trước đó và nói chung, đầu ra của nó không thể được xử lý (xem $dirstack
hoặc $DIRSTACK
mảng của một số shell mặc dù để truy cập các phần tử của ngăn xếp thư mục đó)
Có thể bạn muốn:
pushd "$(mktemp -d)" &&
popd &&
rmdir "$OLDPWD"
Hoặc là
cd "$(mktemp -d)" &&
cd - &&
rmdir "$OLDPWD"
Mặc dù, tôi sẽ sử dụng:
tmpdir=$(mktemp -d) || exit
(
cd "$tmpdir" || exit # in a subshell
# do what you have to do in that tmpdir
)
rmdir "$tmpdir"
Trong mọi trường hợp, pushd "$(mktemp -d)"
không chạy pushd
trong một subshell. Nếu có, nó không thể thay đổi thư mục làm việc. Đó là mktemp
chạy trong một subshell. Vì nó là một lệnh riêng biệt, nó phải chạy trong một quy trình riêng. Nó viết đầu ra của nó trên một đường ống và quá trình vỏ đọc nó ở đầu kia của đường ống.
ksh93 có thể tránh quá trình riêng biệt khi lệnh được xây dựng, nhưng ngay cả ở đó, nó vẫn là một khung con (một môi trường làm việc khác) mà lần này được mô phỏng thay vì dựa vào môi trường riêng biệt thường được cung cấp bằng cách giả mạo. Ví dụ, trong ksh93
, a=0; echo "$(a=1; echo test)"; echo "$a"
không có ngã ba nào được tham gia, nhưng vẫn echo "$a"
xuất ra kết quả 0
.
Ở đây, nếu bạn muốn lưu trữ đầu ra của mktemp
một biến, cùng lúc với việc bạn chuyển nó tới pushd
, với zsh
, bạn có thể làm:
pushd ${tmpdir::="$(mktemp -d)"}
Với các vỏ giống như Bourne khác:
unset tmpdir
pushd "${tmpdir=$(mktemp -d)}"
Hoặc để sử dụng đầu ra $(mktemp -d)
nhiều lần mà không lưu trữ rõ ràng trong một biến, bạn có thể sử dụng zsh
các hàm ẩn danh:
(){pushd ${1?} && cd - && rmdir $1} "$(mktemp -d)"
trap
trình xử lý có thể dọn sạch thư mục nếu quá trình được chọc bởi tín hiệu.