Відповіді:
Команда, яку ви шукаєте, є pushd
і popd
.
Ви можете переглянути практичний робочий приклад pushd
і popd
з тут .
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
на випадок, коли ви хочете переходити між двома каталогами, використовуючи одну і ту ж команду, але я не впевнений, наскільки це специфічно для оболонки та дистрибутива / ядра.
OLDPWD
існує у всіх оболонках POSIX, але це марно для цього питання, яке задається питанням, як вийти за рамки цього питання (вже вказується, cd -
що є ярликом cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
замість просто pushd /tmp/dir1
?
pushd /tmp/dir1
повинен працювати просто чудово.
pushd
та popd
переміщаючи дерево каталогів вперед та назад. Ваша відповідь вже правильна.
Ви не вказали, яку оболонку використовуєте, тому нехай це буде приводом для реклами zsh.
Так, у нас є більше історій для cd
, а саме cd -2
, і cd -4
так далі Дуже зручно це cd -
TAB, особливо з системою закінчення і включені квітами:
Це те, що у мене є в .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'
І результат:
bash
, це правильна відповідь. Не видаляйте його.
setopt AUTO_PUSHD
, жодна з перерахованих настройок не потрібна . PUSHD_MINUS
повертає почуття cd +
та cd -
(питання смаку), CDABLE_VARS
не має значення для стеків каталогів, а zstyle
виклик, наведений тут, просто додає забарвлення виводу завершення стека каталогу. Однак потрібно ініціалізувати підсистему завершення autoload -U compinit && compinit
.
Щоб відповісти на ваше запитання щодо "додаткової історії". Жодна cd -
функція в Bash не підтримує лише одну директорію, до якої можна "перевернути" назад. Як стверджує @Ramesh у своїй відповіді. Якщо вам потрібна довша історія каталогів, ви можете використовувати pushd
та popd
зберегти каталог або повернутися до попереднього.
Ви також можете побачити список того, що зараз знаходиться в стеку з dirs
командою.
Детальне пояснення можна знайти з цієї відповіді під назвою: Як використовувати команди pushd та popd? .
У вас стільки історії, скільки ви хочете:
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"
}
Це функція оболонки, яка повинна дозволити будь-якій сумісній з POSIX оболонці пропонувати історію zsh
стилю cd
. Він виконує всю свою роботу, не залучаючи жодної нижньої оболонки, і я вважаю, що її потік є досить здоровим - він, здається, справляє всі випадки правильно при помірному тестуванні.
Функція намагається грати якомога приємніше зі своїм оточенням, хоча це все ще покладається на повністю портативний синтаксис - вона робить лише одне припущення, і це те, що $DIRSTACK
змінна середовища є його властивістю робити так, як і буде.
Він канонізує всі шляхи, в яких він зберігається, $DIRSTACK
і серіалізує їх на одних лапках, хоча це гарантує безпечне котирування та серіалізацію перед тим, як додати його до значення змінної, і не повинно мати жодних проблем із будь-якими спеціальними символами будь-якого типу . Якщо встановлена $DIRSTACKMAX
змінна середовище, вона використовуватиме її як верхню межу для кількості шляхів, які вона зберігає в історії, в іншому випадку ліміт - один.
Якщо ви завантажуєте цю функцію, ви cd
як звичайно, але також зможете виконати cd -[num]
відкликання назад через історію каталогу змін.
Основним механізмом функції є cd
сам - і ${OLD,}PWD
змінні середовища. POSIX вказує, що cd
змінювати їх для кожного переміщення шляху - і таким чином, це просто використовує вбудовані змінні оболонки і зберігає значення стільки часу, скільки вам подобається.
Acd_func.sh скрипт робить саме те , що ви описуєте. По суті, вона перевантажує cd
функцію і дає змогу вводити cd --
список попередньо відвіданих каталогів, з яких ви можете вибрати номер. Мені дуже важко використовувати bash без цього, і це перше, що я встановлюю на новій системі.
Інші вже висвітлювали деякі цікаві рішення. Деякий час тому я створив власне рішення пов'язаної проблеми, яку можна було б швидко змінити, щоб зробити "пряму історію". Я в основному хотів "позначити" кілька часто використовуваних каталогів, і хотів, щоб усі відкриті оболонки бачили їх, і щоб вони зберігалися між перезавантаженнями.
#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
}
В принципі , я б просто зробити , label foo
щоб зателефонувати в поточний каталог foo
, а потім з будь-якої оболонки, goto foo
whould cd
прямо там. Порожній аргумент: label
створить ціль за замовчуванням для goto
.
Я не переймався впровадженням автоматизованого видалення псевдонімів, але в іншому випадку я все ще використовую це в дещо зміненому вигляді.
Ви можете використовувати мою функцію "Історія cd" з http://fex.belwue.de/fstools/bash.html
Він запам'ятовує кожен каталог, де ви були, і з "cdh" ви побачите список останніх 9 каталогів. Просто введіть номер і ви знову в цьому каталозі.
Приклад:
framstag @ wupp: /: cdh 1: / usr / local / bin 2: / вар 3: / 4: / tmp / 135_pana / 1280 5: / tmp / 135_pana 6: / tmp / weihnachtsfeier 7: / тмп 8: / місцевий / домашній / фрамстаг виберіть: 4 framstag @ wupp: / tmp / 135_pana / 1280:
cdh працює з autocd aka "cd without cd": вам не потрібно вводити cd або pushd.
Я б рекомендував вам розширити функцію 'cd':
Він забезпечує наступні функції для полегшення життя:
для bash , в основному: замість того, щоб використовувати cd pushd
для зміни Directorys, вони зберігаються (мається на увазі стеки)
pushd /home; pushd /var; pushd log
Щоб побачити використання стека dirs
та простішу навігацію (щоб отримати номери "записів стека", використовуйте:
dirs -v
Вихід:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Тепер використовуйте ці числа за допомогою cd
та ~
як:
cd ~1
Але тепер ці цифри переставляють зараз, і позиція "0" зміниться, тому просто pushd
каталог у верхню позицію двічі (або використовуйте манекен на позицію 0) на зразок:
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
тепер 1..3 збереже там позицію, я десь прочитав це, але більше не знаю, так що вибачте, що не надав кредит
(звільнити поточний каталог із стека / видалити його з використання історії popd
)
Дивіться функцію cdh у "Програмуванні оболонки, 4e" на сторінці 312. Вона зберігає історію в масиві.
Ось більш вдосконалена версія: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Він зберігає історію у файлі CDHISTFILE і дозволяє перейти до останнього каталогу, що містить рядок, наприклад,
cd -src
Він встановлюється над існуючою командою cd, виконуючи an alias cd=_cd
Просто хотілося додати fzf-позначки як можливе рішення.
Після встановлення він дає вам команду відмітити і перейти, щоб додати та шукати каталоги в закладках (так, це не зовсім повна історія, лише ті, які ви додали до закладок).
Проблема, з якою у мене виникає конкретна поведінка сеансу pushd / popd, тобто я хотів би мати однаковий стек на різних сесіях bash або так, що можливо для fzf-знаків.
Я спробував відповідь, яку дав @mikeserv, але це не дуже спрацювало для мене. Я не міг зрозуміти, як це виправити, тому я просто написав своє:
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[@]}}")
}
Це також доступно як GitHub Gist . Щоб скористатися цією функцією, просто вставте цю функцію у свою .bashrc
або подібну, і ви зможете робити такі речі, як cd -5
повернутися до 5- ої останньої директорії, в якій ви знаходилися. cd -h
Дасте вам огляд вашої історії.