Чи є у нас більше історії для 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.