Ответы:
Команда, которую вы ищете, это 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
стоит упомянуть, что, кроме того , ни одна из вышеперечисленных настроек не требуется для получения вездесущего стека каталогов с завершением на складе zsh. PUSHD_MINUS
меняет смысл cd +
и cd -
(вопрос вкуса), не CDABLE_VARS
имеет отношения к стекам каталогов, и zstyle
приведенный здесь вызов просто добавляет окраску к выводу завершения стека каталогов. Однако необходимо инициализировать подсистему завершения с помощью autoload -U compinit && compinit
.
Чтобы ответить на ваш вопрос относительно «больше истории». Никакая cd -
функция в Bash не поддерживает только один каталог, который вы можете «перевернуть» обратно. Как @Ramesh заявляет в своем ответе. Если вам нужна более длинная история каталогов, вы можете использовать pushd
и, popd
чтобы сохранить каталог или вернуться к предыдущему.
Вы также можете увидеть список того, что в данный момент находится в стеке с помощью dirs
команды.
Подробное объяснение можно найти в ответе: « Как использовать команды pushd и popd? ,
Вы можете установить и использовать мою утилиту dirhistory для bash.
По сути, это демон, который собирает изменения каталогов со всех ваших оболочек, и программа Cdk, которая отображает историю и позволяет вам выбрать любой каталог для переключения (так что вы не ограничены стеком).
У вас столько истории, сколько вы хотите:
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 history" с http://fex.belwue.de/fstools/bash.html
Он запоминает каждый каталог, в котором вы были, и с помощью «cdh» вы увидите список последних 9 каталогов. Просто введите номер, и вы снова в этом каталоге.
Пример:
framstag @ wupp: /: cdh 1: / usr / local / bin 2: / var 3: / 4: / tmp / 135_pana / 1280 5: / tmp / 135_pana 6: / tmp / weihnachtsfeier 7: / tmp 8: / местный / дом / фрамстаг выберите: 4 framstag @ wupp: / TMP / 135_pana / 1280:
cdh работает с autocd aka "cd без cd": вам не нужно вводить cd или pushd.
Я бы хотел порекомендовать вам мою расширенную функцию "cd":
Это обеспечивает следующие функции, чтобы сделать жизнь проще:
для bash , в основном: вместо использования cd используйте pushd
для изменения каталогов, чтобы они сохранялись (то есть сложены)
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, выполнив alias cd=_cd
Просто хотел добавить fzf-mark как возможное решение.
После установки он дает вам команды пометить и перейти к добавлению и поиску закладок в каталогах (да, это не совсем полная история, только те, которые вы добавили в закладки сами).
Проблема, которую я имею с pushd / popd, это специфичное для сессии поведение, то есть я хотел бы иметь один и тот же стек в другой сессии bash или около того, что возможно для fzf-mark.
Я попробовал ответ, который дал @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
Он даст вам обзор вашей истории.