Câu trả lời:
Lệnh bạn đang tìm là pushd
và popd
.
Bạn có thể xem một ví dụ làm việc thực tế của pushd
và popd
từ đây .
mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4
cd /tmp/dir1
pushd .
cd /tmp/dir2
pushd .
cd /tmp/dir3
pushd .
cd /tmp/dir4
pushd .
dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1
$OLDPWD
trường hợp bạn muốn lật qua lại giữa hai thư mục bằng cùng một lệnh, nhưng tôi không chắc chắn mức độ cụ thể của vỏ và phân phối / hạt nhân cụ thể này.
OLDPWD
tồn tại trong tất cả các vỏ POSIX, nhưng câu hỏi này vô dụng đối với câu hỏi này làm thế nào để vượt qua điều đó (câu hỏi đã đề cập đến cd -
đó là lối tắt cho cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
thay vì chỉ pushd /tmp/dir1
?
pushd /tmp/dir1
nên làm việc tốt
pushd
và duyệt popd
qua cây thư mục qua lại. Câu trả lời của bạn đã là câu trả lời đúng.
Bạn đã không chỉ định shell nào bạn đang sử dụng, vì vậy hãy coi đây là lý do để quảng cáo zsh.
Có, chúng tôi có nhiều lịch sử hơn cd
, cụ thể là cd -2
, cd -4
v.v ... Rất tiện lợi cd -
TAB, đặc biệt là với hệ thống hoàn thành và màu sắc được bật:
Đây là những gì tôi có trong .zshrc:
setopt AUTO_PUSHD # pushes the old directory onto the stack
setopt PUSHD_MINUS # exchange the meanings of '+' and '-'
setopt CDABLE_VARS # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'
Và kết quả:
bash
, đây là một câu trả lời hợp lệ. Đừng loại bỏ nó.
setopt AUTO_PUSHD
, không có thiết lập nào ở trên được yêu cầu để có được một ngăn xếp thư mục toàn diện với sự hoàn thành trong kho zsh. PUSHD_MINUS
đảo ngược ý nghĩa cd +
và cd -
(một vấn đề của hương vị), CDABLE_VARS
không liên quan đến ngăn xếp thư mục, và zstyle
lời mời được đưa ra ở đây chỉ đơn giản là thêm màu vào đầu ra của việc hoàn thành ngăn xếp thư mục. Tuy nhiên, người ta phải khởi tạo hệ thống con hoàn thành với autoload -U compinit && compinit
.
Để trả lời câu hỏi của bạn về "lịch sử nhiều hơn". Không có cd -
tính năng nào trong Bash chỉ hỗ trợ một thư mục duy nhất mà bạn có thể "lật" lại. Như @Ramesh nói trong câu trả lời của mình. Nếu bạn muốn có một lịch sử lâu hơn của các thư mục, bạn có thể sử dụng pushd
và popd
lưu một thư mục hoặc quay lại thư mục trước đó.
Bạn cũng có thể xem danh sách những gì hiện có trong ngăn xếp với dirs
lệnh.
Một lời giải thích chi tiết có thể được tìm thấy từ câu trả lời này có tiêu đề: Làm thế nào để tôi sử dụng các lệnh Pushd và popd? .
Bạn có thể cài đặt và sử dụng tiện ích dirhistory của tôi cho bash.
Về cơ bản, đó là một daemon thu thập các thay đổi thư mục từ tất cả các shell của bạn và chương trình Cdk hiển thị lịch sử và cho phép bạn chọn bất kỳ thư mục nào để chuyển sang (vì vậy bạn không bị giới hạn trong một ngăn xếp).
Bạn có nhiều lịch sử như bạn muốn:
cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
set -- "$@" "$DIRSTACK" &&
DIRSTACK='pwd -P >&3; command cd' ||
{ command cd "$@"; return; }
_q() while case "$1" in (*\'*) : ;; (*)
! DIRSTACK="$DIRSTACK '$2$1'" ;;esac
do set -- "${1#*\'}" "$2${1%%\'*}'\''"
done
while [ "$#" -gt 1 ]
do case ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
(*) eval " set $((${1#-}+1))"' "${'"$#}\""
eval ' set -- "$2"'" $2"'
set -- "${'"$1"'}" "$1"'
;;esac; _q "$1"; shift
done
eval " DIRSTACK=; $DIRSTACK &&"'
_q "$OLDPWD" &&
DIRSTACK=$DIRSTACK\ $1
set "$?" "${DIRSTACK:=$1}"'" $1
" 3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}
Đó là một hàm shell sẽ cho phép mọi shell tương thích POSIX cung cấp lịch sử zsh
kiểu cd
. Nó thực hiện tất cả công việc của nó mà không cần gọi một subshell duy nhất, và tôi tin rằng dòng chảy của nó là âm thanh khá - nó dường như xử lý tất cả các trường hợp chính xác trong thử nghiệm vừa phải.
Hàm cố gắng chơi độc đáo với môi trường của nó như có thể trong khi vẫn dựa vào cú pháp hoàn toàn di động - nó chỉ đưa ra một giả định và đó là $DIRSTACK
biến môi trường là thuộc tính của nó.
Nó hợp thức hóa tất cả các đường dẫn mà nó lưu trữ $DIRSTACK
và tuần tự hóa tất cả chúng trên các dấu ngoặc đơn - mặc dù nó đảm bảo mỗi đường dẫn được trích dẫn và tuần tự hóa một cách an toàn trước khi thêm nó vào giá trị của biến và không nên có bất kỳ vấn đề nào với bất kỳ ký tự đặc biệt nào. . Nếu $DIRSTACKMAX
biến môi trường được đặt, nó sẽ sử dụng nó làm giới hạn trên cho số lượng đường dẫn mà nó giữ lại trong lịch sử, nếu không thì giới hạn là một.
Nếu bạn tải chức năng, bạn vẫn cd
bình thường nhưng cũng có thể thực hiện việc cd -[num]
lấy lại thông qua lịch sử thư mục thay đổi của bạn.
Cơ chế chính của hàm là cd
chính nó - và các ${OLD,}PWD
biến môi trường. POSIX chỉ định cd
thay đổi những thay đổi này cho mỗi lần di chuyển đường dẫn - và do đó, điều này chỉ sử dụng các biến dựng sẵn của shell và lưu các giá trị bao lâu tùy thích.
Các acd_func.sh kịch bản thực hiện chính xác những gì bạn mô tả. Về cơ bản, nó làm quá tải cd
chức năng và cho phép bạn nhập cd --
để có danh sách các thư mục đã truy cập trước đó, từ đó bạn có thể chọn theo số. Tôi thấy rất khó để sử dụng bash mà không có điều này nữa, và đó là điều đầu tiên tôi cài đặt trên một hệ thống mới.
Những người khác đã bao gồm một số giải pháp thú vị. Cách đây một thời gian, tôi đã tạo ra giải pháp của riêng mình cho một vấn đề liên quan có thể được sửa đổi nhanh chóng để làm "lịch sử thẳng". Về cơ bản, tôi muốn "gắn nhãn" một vài thư mục thường được sử dụng và muốn tất cả các shell mở để xem chúng và để chúng tồn tại giữa các lần khởi động lại.
#dir_labels
#functions to load and retrieve list of dir aliases
function goto_complete {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
local cur possib
cur="${COMP_WORDS[COMP_CWORD]}"
possib="${!dir_labels[@]}"
COMPREPLY=( $(compgen -W "${possib}" -- ${cur}) )
}
complete -F goto_complete goto
function goto {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
if [ $# -gt 0 ]; then
key="$1"
else
key=default
fi
target="${dir_labels[$key]}"
if [ -d "$target" ]; then
cd "$target"
echo "goto $key: '$target'"
else
echo "directory '$target' does not exist"
fi
}
function label {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
if [ $# -gt 0 ]; then
target="$1"
else
target="default"
fi
dir_labels["$target"]=$PWD
for i in "${!dir_labels[@]}"; do
echo "$i ${dir_labels[$i]}"
done > ~/.dir_labels
}
Về cơ bản tôi chỉ muốn làm label foo
để gọi thư mục hiện hành foo
, và sau đó từ bất cứ shell, goto foo
whould cd
thẳng tới đó. Đối số trống: label
sẽ tạo một mục tiêu mặc định cho goto
.
Tôi không bận tâm đến việc tự động loại bỏ các bí danh, nhưng nếu không, tôi vẫn đang sử dụng điều này ở dạng hơi sửa đổi.
Bạn có thể sử dụng chức năng "lịch sử cd" của tôi từ http://fex.belwue.de/fstools/bash.html
Nó ghi nhớ mọi thư mục nơi bạn đã đến và với "cdh", bạn sẽ thấy một danh sách 9 thư mục cuối cùng. Chỉ cần nhập số và bạn trở lại trong thư mục này.
Thí dụ:
framstag @ wupp: /: cdh 1: / usr / cục bộ / thùng 2: / var 3: / 4: / tmp / 135_pana / 1280 5: / tmp / 135_pana 6: / tmp / weihnachtsfeier 7: / tmp 8: / địa phương / nhà / framstag chọn: 4 framstag @ wupp: / tmp / 135_pana / 1280:
cdh hoạt động với autocd aka "cd without cd": bạn không phải gõ cd hoặc Pushd.
Tôi muốn giới thiệu chức năng 'cd' mở rộng của mình cho bạn:
Nó cung cấp các tính năng sau để làm cho cuộc sống dễ dàng hơn:
về bash , về cơ bản: thay vì sử dụng cd pushd
để thay đổi thư mục, vì vậy chúng được lưu (có nghĩa là xếp chồng)
pushd /home; pushd /var; pushd log
Để xem ngăn xếp sử dụng dirs
và để điều hướng dễ dàng hơn (để lấy số của "mục nhập ngăn xếp", hãy sử dụng:
dirs -v
Đầu ra:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Bây giờ sử dụng những con số này với cd
và ~
như:
cd ~1
Nhưng bây giờ các số này được sắp xếp lại ngay bây giờ và vị trí "0" sẽ thay đổi, vì vậy chỉ cần pushd
thư mục đến vị trí trên cùng hai lần (hoặc sử dụng một hình nộm ở vị trí 0) như:
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
Bây giờ 1..3 sẽ giữ nguyên vị trí tôi đọc được ở đâu đó nhưng không biết nữa, rất tiếc vì đã không cung cấp tín dụng
(để giải phóng thư mục hiện tại khỏi ngăn xếp / xóa nó khỏi lịch sử sử dụng popd
)
Xem chức năng cdh trong "Lập trình Shell, 4e" trên trang 312. Nó giữ lịch sử trong một mảng.
Đây là phiên bản nâng cao hơn: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Nó lưu trữ lịch sử trong tệp CDHISTFILE và cho phép thay đổi thư mục gần đây nhất có chứa một chuỗi, ví dụ:
cd -src
Nó tự cài đặt qua lệnh cd hiện có bằng cách thực hiện alias cd=_cd
Chỉ muốn thêm dấu fzf như một giải pháp có thể.
Sau khi cài đặt, nó cung cấp cho bạn dấu lệnh và nhảy để thêm và tìm kiếm các thư mục được đánh dấu (vâng, nó không chính xác là lịch sử đầy đủ, chỉ có những cái bạn tự đánh dấu).
Vấn đề tôi gặp phải với Pushd / popd đó là hành vi cụ thể của phiên, tức là tôi muốn có cùng ngăn xếp trên phiên bash khác nhau hoặc do đó có thể xảy ra đối với các dấu fzf.
Tôi đã thử câu trả lời mà @mikeerv đưa ra, nhưng nó không hiệu quả lắm đối với tôi. Tôi không thể tìm ra cách khắc phục nó, vì vậy tôi chỉ tự viết:
cd() {
# Set the current directory to the 0th history item
cd_history[0]=$PWD
if [[ $1 == -h ]]; then
for i in ${!cd_history[@]}; do
echo $i: "${cd_history[$i]}"
done
return
elif [[ $1 =~ ^-[0-9]+ ]]; then
builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
return
else
builtin cd "$@" || return # Bail if cd fails
fi
# cd_history = ["", $OLDPWD, cd_history[1:]]
cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}
Điều này cũng có sẵn như là một GitHub Gist . Để sử dụng tính năng này, chỉ cần dán chức năng vào .bashrc
hoặc tương tự, và bạn sẽ có thể thực hiện những việc như cd -5
quay lại thư mục thứ 5 cuối cùng mà bạn đã tham gia. cd -h
Sẽ cho bạn cái nhìn tổng quan về lịch sử của bạn.