Что такое быстрый способ командной строки для переключения между несколькими каталогами для системного администрирования?


46

Что такое быстрый способ командной строки для переключения между несколькими каталогами для системного администрирования? Я имею в виду, что я могу использовать pushd .и popdдля переключения, но что если я захочу хранить кратные числа и циклически их перебирать, вместо того, чтобы постоянно выталкивать их из нижней части стека?


$CDPATHвозможно?
Роайма

6
о боже, я только что узнал об этом cd -после того, как спровоцировал поиск в Google.
Nacht - Восстановить Монику

@Nacht: Как вы перемещались по файловой структуре раньше ??
одинокий катер

1
Делали cdвезде вручную. Было больно. Использовал автозаполнение с помощью клавиши табуляции, хотя.
Воломике

1
Может быть, вы хотите попробовать . Чрезвычайно удобно, когда вы много прыгаете в одной и той же паре режиссеров.
Рольф

Ответы:


28

Используйте , pushdа затем специальные имена каталогов в вашем стеке каталогов: ~1, ~2и т.д.

Пример:

tmp $ dirs -v
 0  /tmp
 1  /tmp/scripts
 2  /tmp/photos
 3  /tmp/music
 4  /tmp/pictures
tmp $ cd ~3
music $ dirs -v
 0  /tmp/music
 1  /tmp/scripts
 2  /tmp/photos
 3  /tmp/music
 4  /tmp/pictures
music $ cd ~2
photos $ cd ~4
pictures $ cd ~3
music $ cd ~1
scripts $ 

Наиболее эффективный способ использовать pushdэтот способ - загрузить список каталогов, затем добавить еще один каталог в качестве текущего каталога, а затем вы можете переходить между статическими числами, не влияя на положение каталогов в вашем стеке.


Также стоит отметить, что cd -вы попадете в последний каталог, в котором вы были. Так и будет cd ~-.

Преимущество ~-над только в -том , что -является специфичным для cd, в то время как ~-расширяется вашей оболочки так же, как ~1, ~2и т.д. есть. Это удобно при копировании файла между очень длинными путями каталогов; например:

cd /very/long/path/to/some/directory/
cd /another/long/path/to/where/the/source/file/is/
cp myfile ~-

Вышеуказанное эквивалентно:

cp /another/long/path/to/where/the/source/file/is/myfile /very/long/path/to/some/directory/

1
Можно также использоватьcd -
Volomike

cd -действует как Forth DROP DUP, например, если вы начинаете с в каталоге a , со стеком abcd , a cd -изменяет стек на bbcd . Возможно, это bashошибка, так как секунда cd -меняет стек обратно на abcd . Из этого мы можем сделать вывод, что cd -в дополнение к изменению стека используется некоторая отдельная структура данных для хранения предыдущего каталога.
agc

3
@agc, cd -использует $OLDPWDи ничего больше.
Подстановочный

Так что, возможно, cd -раньше была функция bash , затем они добавили стек, но боялись сломать старый код больше, чем хотели более простой дизайн. Коррекция к предыдущему, cd -действует примерно как Forth. OLDPWD @ SWAP OLDPWD ! DUP . В отличие от этого cd foo, cd -печатает имя замененного каталога.
agc

Или всегда есть интерактивная оболочка pushd (другие ответы на этот вопрос включают autojump и т. Д. И т. Д.).
бесполезно

42

bash«S встроенный pushdс +и -параметры могут вращаться стек каталогов. Синтаксис может немного сбить с толку, возможно, потому, что этот стек является массивом на основе нуля . Эти простые функции-обертки циклически перемещаются по стеку каталогов:

# cd to next     directory in stack (left  rotate)
ncd(){ pushd +1 > /dev/null ; }
# cd to previous directory in stack (right rotate)
pcd(){ pushd -0 > /dev/null ; }

Тест: настроить стек из четырех каталогов.

dirs -c   # clear directory stack
cd /home ; pushd /etc ; pushd /bin ; pushd /tmp

Теперь / tmp является текущим каталогом, а стек выглядит так:

/tmp /bin /etc /home

Перейдите к следующему каталогу в стеке (и покажите его) четыре раза:

ncd ; pwd ; ncd ; pwd ; ncd ; pwd ; ncd ; pwd

Выход:

/bin
/etc
/home
/tmp

Перейдите к предыдущему каталогу в стеке (и покажите его) четыре раза:

pcd ; pwd ; pcd ; pwd ; pcd ; pwd ; pcd ; pwd

Выход:

/home
/etc
/bin
/tmp

Примечание cd -: ответ Wildcard помог проиллюстрировать, как cd -не используется массив $ DIRSTACK (он использует переменную $ OLDPW ), так что cd -это не влияет на $ DIRSTACK так, как должен использоваться своп на основе стека. Чтобы исправить это, вот простая своп- функция на основе $ DIRSTACK :

scd() { { pushd ${DIRSTACK[1]} ; popd -n +2 ; } > /dev/null ; }

Контрольная работа:

dirs -c; cd /tmp; \
pushd /bin; \
pushd /etc; \
pushd /lib; \
pushd /home; \
scd; dirs; scd; dirs

Выход:

/bin /tmp
/etc /bin /tmp
/lib /etc /bin /tmp
/home /lib /etc /bin /tmp
/lib /home /etc /bin /tmp
/home /lib /etc /bin /tmp

Мое разочарование в том, что я хочу положить предметы в стек и держать их там, пока не решу очистить стек. Таким образом, я могу толкать, толкать, толкать, а затем циклически проходить по каждому из трех каталогов по мере необходимости. Скажем, например, мне нужно переключаться между тремя каталогами, как будто они похожи на вкладки браузера, и переходить назад и вперед, пока я не закрою вкладку. Это решает эту проблему способом командной строки?
Volomike

5
Да, я верю, что попробуйте. Чтобы удалить верхний элемент, сделайте popd, чтобы удалить его, не меняя директорий, сделайте popd -n. Для очистки стека делай dirs -c. Жаль, что дизайнеры bash похоронили такие полезные функции в неинтуитивном синтаксисе. Смотрите man bashпод pushd, dirsи т.д.
АРУ

Работает! И было ясно, как грязь в документах. Мне нравится простота, теперь, когда я знаю технику.
Volomike

13

Я предлагаю вам установить FASD . Это дает вам возможность быстро перейти к любому каталогу, в котором вы уже были, введя только небольшую часть его имени.

Пример: если вы посетили /home/someName/scripts/, вы можете перейти туда, просто набрав, z scrнапример. Это намного удобнее, чем запоминать порядок в стеке истории или что-то подобное.


10

Когда вы cdгде-то, Bash хранит старый рабочий каталог переменную окружения $OLDPWD.

Вы можете переключиться обратно в этот каталог с помощью cd -, что эквивалентно cd "$OLDPWD".

Вы можете прыгать туда-сюда между каталогами следующим образом:

blue$ cd ~/green
green$ cd -
blue$ cd -
green$

6

Я написал скрипт xyzzyдля этого:

#!/bin/bash

i="$1"
i=$((${i//[^0-9]/}))
i="$(($i-1+0))"

b="$2"
b=$((${b//[^0-9]/}))
b="$(($b-1+0))"

if [ -z "$XYZZY_INDEX" ]; then
    XYZZY_INDEX="$((-1))"
fi

if [ ! -f "/tmp/xyzzy.list" ]; then
    touch /tmp/xyzzy.list
    chmod a+rw /tmp/xyzzy.list
fi
readarray -t MYLIST < /tmp/xyzzy.list

showHelp(){
read -r -d '' MYHELP <<'EOB'
xyzzy 1.0

A command for manipulating escape routes from grues. Otherwise known as a useful system admin
tool for storing current directories and cycling through them rapidly. You'll wonder why this
wasn't created many moons ago.

Usage: xyzzy [options]

help/-h/--help      Show the help.

this/-t/--this      Store the current directory in /tmp/xyzzy.list

begone/-b/--begone  Clear the /tmp/xyzzy.list file. However, succeed with a number and
            it clears just that item from the stored list.

show/-s/--show      Show the list of stored directories from /tmp/xyzzy.list

. #         Use a number to 'cd' to that directory item in the stored list. This syntax is odd:

            . xyzzy 2

            ...would change to the second directory in the list

. [no options]      Use the command alone and it cd cycles through the next item in the stored 
            list, repeating to the top when it gets to the bottom. The dot and space before xyzzy
            is required in order for the command to run in the current shell and not a subshell:

            . xyzzy

Note that you can avoid the odd dot syntax by adding this to your ~/.bashrc file:

  alias xyzzy=". xyzzy"

and then you can do "xyzzy" to cycle through directories, or "xyzzy {number}" to go to a
specific one.

May you never encounter another grue.

Copyright (c) 2016, Mike McKee <https://github.com/volomike>
EOB
    echo -e "$MYHELP\n"
}

storeThis(){
    echo -e "With a stroke of your wand, you magically created the new escape route: $PWD"
    echo "$PWD" >> /tmp/xyzzy.list
    chmod a+rw /tmp/xyzzy.list
}

begoneList(){
    if [[ "$b" == "-1" ]]; then
        echo "POOF! Your escape routes are gone. We bless your soul from the ever-present grues!"
        >/tmp/xyzzy.list
        chmod a+rw /tmp/xyzzy.list
    else
        echo -n "Waving your wand in the dark, you successfully manage to remove one of your escape routes: "
        echo "${MYLIST[${b}]}"
        >/tmp/xyzzy.list
        chmod a+rw /tmp/xyzzy.list
        for x in "${MYLIST[@]}"; do
            if [[ ! "$x" == "${MYLIST[${b}]}" ]]; then
                echo "$x" >> /tmp/xyzzy.list
            fi
        done
    fi
}

showList(){
    echo -e "These are your escape routes:\n"
    cat /tmp/xyzzy.list
}

cycleNext(){
    MAXLINES=${#MYLIST[@]}
    XYZZY_INDEX=$((XYZZY_INDEX+1))
    if [[ $XYZZY_INDEX > $(($MAXLINES - 1)) ]]; then
        XYZZY_INDEX=0
    fi
    MYLINE="${MYLIST[${XYZZY_INDEX}]}"
    cd "$MYLINE";
}

switchDir(){
    MYLINE="${MYLIST[${i}]}"
    cd "$MYLINE";
}

if [[ "$@" == "" ]];
then
    cycleNext
fi;

while [[ "$@" > 0 ]]; do case $1 in
    help) showHelp;;
    --help) showHelp;;
    -h) showHelp;;
    show) showList;;
    -s) showList;;
    --show) showList;;
    list) showList;;
    this) storeThis;;
    --this) storeThis;;
    -t) storeThis;;
    begone) begoneList;;
    --begone) begoneList;;
    *) switchDir;;
    esac; shift
done

export XYZZY_INDEX

Я использую это для копирования в /usr/binпапку, а затем chmod a+xна нее. Затем я редактирую свой root и ~/.bashrcфайл учетной записи пользователя, чтобы включить эти строки внизу:

alias xyzzy='. xyzzy'
alias xy='. xyzzy'

«Xy» - это сокращенная форма команды для быстрого набора текста.

Затем я могу сохранить текущий каталог в списке с помощью ...

xyzzy this

... и повторите при необходимости. Как только я заполняю этот список необходимыми каталогами, они остаются там до тех пор, пока я не перезагружаю компьютер, потому что именно тогда / tmp снова очищается. Я могу тогда напечатать ...

xyzzy show

... для просмотра списка сохраненных каталогов. Для того, чтобы перейти в каталог, у меня есть два варианта. Один из вариантов - указать путь по индексу (и это индекс на основе 1) следующим образом:

xyzzy 2

... который переключился бы на каталог, который является вторым пунктом в списке. Или я мог бы опустить индекс и просто сделать:

xyzzy

... чтобы он прошел через каждый каталог, как мне нужно. Чтобы получить больше команд, введите:

xyzzy help

Конечно, работать веселее с глупыми эхо-заявлениями, которые я добавил.

Обратите внимание, что xyzzy - это ссылка на текстовое приключение в Collosal Cave , где ввод xyzzy позволит вам переключаться между двумя комнатами в игре, чтобы избежать неприятностей.


2
+1 Я начал играть с этим. Это хорошо, но, похоже, ничего не получится, если каталоги еще не добавлены, а вы вводите просто xyzzy. Требуется еще один тест для MAXLINES -eq 0 в cyclenext ().
Джо

5

Я использую небольшой скрипт с именем z [link] , который также может быть интересен, даже если он не выполняет то, что вы просили.

NAME
       z - jump around

SYNOPSIS
       z [-chlrtx] [regex1 regex2 ... regexn]

AVAILABILITY
       bash, zsh

DESCRIPTION
       Tracks your most used directories, based on 'frecency'.

       After  a  short  learning  phase, z will take you to the most 'frecent'
       directory that matches ALL of the regexes given on the command line, in
       order.

       For example, z foo bar would match /foo/bar but not /bar/foo.

Может быть, я что-то пропустил, но где найти сам скрипт z?
Джо

Извините, ссылка была на z. Будет редактировать, чтобы было легче увидеть.
Graipher

5

Есть также cd_funcот Петра Маринова, в основном cdс историей до 10 записей: http://linuxgazette.net/109/misc/marinov/acd_func.html

# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

Просто используйте cd --для отображения списка из последних 10 каталогов, в которые вы редактировали, cdи cd -N(где Nнаходится индекс записи), чтобы перейти туда.


4

Я в основном использую ZSH с профилем oh-my-zsh . Вы можете ввести в терминал следующее совпадение:

# cd /ho

Затем вы можете просто использовать стрелки (вверх и вниз), чтобы просмотреть всю историю оболочки, которая показывает только те записи, которые начинаются с символов выше. Так, например, если вы пошли в /home/morfik/Desktop/и /home/morfik/something/, вы можете очень быстро переключаться между каталогами. Неважно, сколько записей в истории оболочки у вас есть, но когда у вас их много, просто используйте лучшее выражение, то есть, cd /home/morfи здесь нажимайте стрелки вверх / вниз на клавиатуре.

Есть и другой способ достижения решения. В этом случае вы должны использовать tmux и FZF . Затем вы просто создаете горячую клавишу, например ctrl-r, и когда вы нажимаете ее, ваше текущее окно будет разделено, и вы увидите это:

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

Теперь вы можете использовать выражения для поиска в списке. Я только что набрал ^cd /media, который возвращает только те записи, которые начинаются с фразы. Конечно, вы можете просто набрать, 'cd 'homeчтобы соответствовать команде, а также полное имя каталога (не путь, просто имя):

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


4

Вы можете достичь этого с помощью нескольких псевдонимов в вашем ~/.bashrc(или эквивалентном)

Основная цель - почти минимальный набор текста (например, d5переход к каталогу № 5 в пуле) для переключения между каталогами в пуле. Также мы хотим упростить добавление / удаление каталогов в / из пула:

alias pd=pushd
alias po=popd
alias d='dirs -v'
alias d0=d
alias d1='pd +1'
alias d2='pd +2'
alias d3='pd +3'
alias d4='pd +4'
alias d5='pd +5'
alias d6='pd +6'
alias d7='pd +7'
alias d8='pd +8'
alias d9='pd +9'
alias d10='pd +10'
# -- feel free to add more aliases if your typical dir pool is larger than 10

Теперь каждый раз, когда вы помещаете каталог в стек, он добавляется в нумерованный пул в позиции 0 (текущий каталог), и вы можете перемещаться (переключать каталоги), используя очень мало ввода ( d<N>), и вы можете просматривать свой нумерованный текущий пул в любом время, просто набрав d.

Несколько примеров использования этих псевдонимов:

Показать нумерованный dir-пул, (текущий dir # 0)

$ d
 0  /tmp
 1  /
 2  /usr

Переключение между каталогами: используйте d<N>

$ d2
$ pwd
/usr

Добавить новый каталог в пул

$ pd /var/log
$ d
 0  /var/log
 1  /usr
 2  /tmp
 3  /

Прыгай еще немного:

$ d3
$ pwd
/

$ d3
$ pwd
/tmp

$ d
 0  /tmp
 1  /
 2  /var/log
 3  /usr

Удалить / вытащить верхний (текущий) каталог из пула

$ po
$ d
 0  /
 1  /var/log
 2  /usr

2

Если у вас установлен iselect , вы можете сделать что-то вроде этого:

$ alias dirselect='cd $(iselect -a $(dirs -l -p | sort -u))'
$ dirselect

Это даст вам полноэкранное интерактивное навигационное меню со стрелками на основе ncurses, чтобы выбрать каталог cdдля.

Если вы не использовали pushdв текущем сеансе оболочки, список каталогов в меню начинается с одной записи - вашего текущего каталога. Если есть только одна запись, этот dirselectпсевдоним будет cdотображаться без экрана меню, поэтому он фактически ничего не делает (кроме того, что мешает cd -делать что-либо полезное)

Чтобы добавить новый каталог в список, используйте pushd dir(или pushd -n dirчтобы добавить в него каталог без cd-ing)

Вы можете предварительно заполнить pushdстек, выполнив что-то вроде следующего в вашем .bashrcили ~/.bash_profile:

for d in /var/tmp /tmp /path/to/somewhere/interesting ; do 
  pushd -n "$d" > /dev/null
done

Вы можете удалить записи с помощью popdили popd -n.

Смотрите help pushd, help popdи help dirsв bash для получения дополнительной информации. И, конечно же , man iselect.

КСТАТИ, iselectвероятно, доступен предварительно упакованный для вашего дистрибутива. Это для Debian и Ubuntu и т. Д., И, вероятно, для других тоже.


2

Если у вас есть 5 или 10 каталогов, которые вы часто используете , и вам не обязательно беспокоиться о недавно использованных 5 или 10 каталогах, настройте некоторые псевдонимы команд, такие как

alias cdw="cd /var/www/html" 

И поэтому, когда я хочу перейти в каталог домашней страницы Apache, я просто набираю, cdwкак я ответил в Эквивалент псевдонима для символической ссылки? ,


2

Я использую прыжок, чтобы быстро изменить рабочий каталог.

Чтобы добавить текущий каталог:

jump -a [bookmark-name]

Чтобы перечислить все ваши закладки:

jump -l

например:

------------------------------------------------------------------
 Bookmark    Path                                                 
------------------------------------------------------------------
 reports     ~/mydir/documents/reports
 projects    ~/documents/projects
 dl          ~/Downloads                     
------------------------------------------------------------------

Теперь вы можете легко перейти в другой каталог:

jump reports

Поддерживает автозаполнение для bash и zsh.


Изменить (в ответ на @Joe): двоичный файл jump-binхранится в /usr/local/bin, и с помощью сценария интеграции bash (на моем компьютере, расположенном в /var/lib/gems/1.9.1/gems/jump-0.4.1/bash_integration/shell_driver), он создает функцию bash, jumpкоторая вызывает jump-bin.


Где живет команда прыжка? У меня его нет, и я не сразу вижу, где его взять.
Джо

2

Я использую aliasдля навигации. Если у вас мало каталогов, к которым часто обращаются, просто установите псевдонимы. Например,

alias e='cd /etc'
alias h='cd /home'
alias al='cd /var/log/apache2/'

Тогда просто

e 

примет вас /etc.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.