Чи є у нас більше історії для CD?


Відповіді:


31

Команда, яку ви шукаєте, є 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

1
Існує також $OLDPWDна випадок, коли ви хочете переходити між двома каталогами, використовуючи одну і ту ж команду, але я не впевнений, наскільки це специфічно для оболонки та дистрибутива / ядра.
mechalynx

4
@ivy_lynx OLDPWDіснує у всіх оболонках POSIX, але це марно для цього питання, яке задається питанням, як вийти за рамки цього питання (вже вказується, cd -що є ярликом cd "$OLDPWD").
Жил "ТАК - перестань бути злим"

2
Чи є причина, яку ви використовуєте cd /tmp/dir1; pushd . замість просто pushd /tmp/dir1?
GnP

@gnp, конкретної причини немає. Це було взято з посилання, на яке я посилався у відповіді. pushd /tmp/dir1повинен працювати просто чудово.
Рамеш

1
Добре, щойно підібрав мою цікавість. Я хотів би запропонувати вам покращити свою відповідь на фактичному прикладі, використовуючи pushdта popdпереміщаючи дерево каталогів вперед та назад. Ваша відповідь вже правильна.
GnP

53

Ви не вказали, яку оболонку використовуєте, тому нехай це буде приводом для реклами 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'

І результат:

введіть тут опис зображення


4
bash bash bash bash
Тім

7
Гаразд, я не видалю цю відповідь, можливо, стане в нагоді іншим.
jimmij

23
Якщо питання конкретно не задається bash, це правильна відповідь. Не видаляйте його.
liori

Що робити, якщо ОП редагує своє запитання, включаючи лише баш, чи буде ця відповідь все ж таки дійсною?
Ooker

3
Можна згадати, що крім цього, для отримання універсального стека каталогів із заповненням на складі zsh setopt AUTO_PUSHD, жодна з перерахованих настройок не потрібна . PUSHD_MINUSповертає почуття cd +та cd -(питання смаку), CDABLE_VARSне має значення для стеків каталогів, а zstyleвиклик, наведений тут, просто додає забарвлення виводу завершення стека каталогу. Однак потрібно ініціалізувати підсистему завершення autoload -U compinit && compinit.
wjv

13

Щоб відповісти на ваше запитання щодо "додаткової історії". Жодна cd -функція в Bash не підтримує лише одну директорію, до якої можна "перевернути" назад. Як стверджує @Ramesh у своїй відповіді. Якщо вам потрібна довша історія каталогів, ви можете використовувати pushdта popdзберегти каталог або повернутися до попереднього.

Ви також можете побачити список того, що зараз знаходиться в стеку з dirsкомандою.

Детальне пояснення можна знайти з цієї відповіді під назвою: Як використовувати команди pushd та popd? .


Я включив посилання з вашої відповіді. Сподіваюся, ви не заперечуєте. :)
Рамеш

@Ramesh - ні вперед.
slm

8

Ви можете встановити та використовувати мою утиліту для архівів для bash.

В основному, це демон, який збирає зміни в каталозі з усіх ваших оболонок, і програма Cdk, яка відображає історію і дозволяє вибирати будь-який каталог для переходу (щоб ви не обмежилися стеком).


7

У вас стільки історії, скільки ви хочете:

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змінювати їх для кожного переміщення шляху - і таким чином, це просто використовує вбудовані змінні оболонки і зберігає значення стільки часу, скільки вам подобається.


@datUser - я знав, що хтось мав дату. ви дуже вітаються
mikeserv

4

Acd_func.sh скрипт робить саме те , що ви описуєте. По суті, вона перевантажує cdфункцію і дає змогу вводити cd --список попередньо відвіданих каталогів, з яких ви можете вибрати номер. Мені дуже важко використовувати bash без цього, і це перше, що я встановлюю на новій системі.



3

Інші вже висвітлювали деякі цікаві рішення. Деякий час тому я створив власне рішення пов'язаної проблеми, яку можна було б швидко змінити, щоб зробити "пряму історію". Я в основному хотів "позначити" кілька часто використовуваних каталогів, і хотів, щоб усі відкриті оболонки бачили їх, і щоб вони зберігалися між перезавантаженнями.

#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 foowhould cdпрямо там. Порожній аргумент: labelстворить ціль за замовчуванням для goto.

Я не переймався впровадженням автоматизованого видалення псевдонімів, але в іншому випадку я все ще використовую це в дещо зміненому вигляді.


2

Ви можете використовувати мою функцію "Історія 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.


2

Я б рекомендував вам розширити функцію 'cd':

https://github.com/dczhu/ltcd

введіть тут опис зображення

Він забезпечує наступні функції для полегшення життя:

  • Загальний список реєстру, який показує нещодавно відвідані дріри з усіх вкладок / вікон терміналів.
  • Місцевий список реєстру, який є локальним для поточного сеансу оболонки.
  • Обидва списки підтримують швидку навігацію за допомогою j / k (вниз / вгору), цифр та пошуку слів.
  • Глобальний вільний стрибок (наприклад, "cd dir" або "cd ar", щоб перейти до / path / to / foo / bar / directory /).

Гм, виглядає багатообіцяюче. Я перевірю це.
ddnomad

1

для 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)


1

Дивіться функцію cdh у "Програмуванні оболонки, 4e" на сторінці 312. Вона зберігає історію в масиві.

Ось більш вдосконалена версія: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

Він зберігає історію у файлі CDHISTFILE і дозволяє перейти до останнього каталогу, що містить рядок, наприклад,

cd -src

Він встановлюється над існуючою командою cd, виконуючи an alias cd=_cd


1

Просто хотілося додати fzf-позначки як можливе рішення.

Після встановлення він дає вам команду відмітити і перейти, щоб додати та шукати каталоги в закладках (так, це не зовсім повна історія, лише ті, які ви додали до закладок).

Проблема, з якою у мене виникає конкретна поведінка сеансу pushd / popd, тобто я хотів би мати однаковий стек на різних сесіях bash або так, що можливо для fzf-знаків.


0

Я спробував відповідь, яку дав @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Дасте вам огляд вашої історії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.