Сбой командной строки при использовании дерева каталогов / имени файла

В системе с Ubuntu 14.04 и bash меня есть переменная PS1 заканчивающаяся следующим содержимым:

 \u@\h:\w\$ 

так что приглашение появится как

 user@machinename:/home/mydirectory$ 

Иногда, однако, текущий каталог имеет длинное имя или находится внутри каталогов с длинными именами, поэтому запрос выглядит так:

 user@machinename:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name$ 

Это заполнит линию в терминале, и курсор перейдет к другой строке, что раздражает.

Я хотел бы вместо этого получить что-то вроде

 user@machinename:/home/mydirectory1/...another_long_name$ 

Есть ли способ определить переменную PS1 для «обертывания» и «компактного» имени каталога, чтобы никогда не превышать определенное количество символов, получив более короткое приглашение?

7 Solutions collect form web for “Сбой командной строки при использовании дерева каталогов / имени файла”

Прежде всего, вы можете просто изменить \w с \W Таким образом, печатается только имя текущего каталога, а не весь его путь:

 terdon@oregano:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name $ PS1="\u@\h:\W \$ " terdon@oregano:my_actual_directory_with_another_long_name $ 

Этого может быть недостаточно, если имя каталога слишком велико. В этом случае вы можете использовать для этого переменную PROMPT_COMMAND . Это специальная переменная bash, значение которой выполняется как команда перед каждым приглашением. Таким образом, если вы установите это для функции, которая задает нужную подсказку в зависимости от длины пути вашего текущего каталога, вы можете получить эффект, который вам нужен. Например, добавьте эти строки в ваш ~/.bashrc :

 get_PS1(){ limit=${1:-20} if [[ "${#PWD}" -gt "$limit" ]]; then ## Take the first 5 characters of the path left="${PWD:0:5}" ## ${#PWD} is the length of $PWD. Get the last $limit ## characters of $PWD. right="${PWD:$((${#PWD}-$limit)):${#PWD}}" PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] ${left}...${right} \$\[\033[00m\] " else PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] " fi } PROMPT_COMMAND=get_PS1 

Эффект выглядит так:

 terdon@oregano ~ $ cd /home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name terdon@oregano /home...th_another_long_name $ 

Добавление в возвращение символа является моим основным решением для этого

Поэтому моя подсказка (которая имеет и другие вещи, делая ее еще дольше) выглядит так:

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

Вы заметите, что $ возвращается как новая строка

Я достигаю этого с помощью

 HOST='\[\033[02;36m\]\h'; HOST=' '$HOST TIME='\[\033[01;31m\]\t \[\033[01;32m\]' LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`' PS1=$TIME$USER$HOST$LOCATION 

Обратите внимание, что, несмотря на то, что на отдельной строке очень большие деревья каталогов, такие как

/home/durrantm/Dropbox/96_2013_archive/work/code/ruby__rails сокращены до

 /home/durrantm/Dropbox/_/code/ruby__rails 

т.е. «топ-3 каталогов / _ / дно двух каталогов», которые, как правило, меня волнуют

Это гарантирует, что линия никогда не станет слишком длинной из-за длины дерева каталогов. Если вы всегда хотите, чтобы полное дерево каталогов только изменило LOCATION, т.е.

 LOCATION=' \[\033[01;34m\]`pwd`' 

Создано ~ / .bash_prompt:

 maxlen=36 # set leftlen to zero for printing just the right part of the path leftlen=19 shortened="..." # Default PWD nPWD=${PWD} if [ ${#nPWD} -gt $maxlen ]; then offset=$(( ${#nPWD} - $maxlen + $leftlen )) nPWD="${nPWD:0:$leftlen}${shortened}${nPWD:$offset:$maxlen}" else nPWD='\w' fi echo "\u@\h:$nPWD\$ " 

Добавлено в мой файл ~ / .bash_profile:

 function prompt_command { export PS1=$(~/.bash_prompt) } export PROMPT_COMMAND=prompt_command 

Выход:

 user@machinename:/home/mydirectory1/...another_long_name$ 

Не решение для сокращения длинных путей, но удобный способ получить лучший обзор при сохранении всей информации о пути, добавляет новую строку перед последним символом. Таким образом, курсор начинается всегда в том же столбце, даже если путь достаточно длинный, чтобы обернуть его, но ваши оконные окна консоли должны быть достаточно высокими, чтобы слишком быстро прокручивать предыдущие строки. Я удалил цветовые коды для большей ясности:

 murphy@seasonsend:~ $ echo $PS1 \u@\h:\w\n\$ murphy@seasonsend:~ $ 

Я использую это, он обертывается на несколько строк и отступов по длине user@host поэтому он предполагает, что текущий PS1 эффективно « \u@\h:\w$ ». Он не усекает путь и адаптируется к текущей ширине терминала. Он только разбивает путь на / , поэтому он не элегантно справляется с действительно длинными каталогами (но он сохраняет пробелы для выбора / копирования). Это гарантирует, что у вас всегда есть доступное для ввода как минимум 20 символов.

 readonly _PS1="${PS1}" 2>/dev/null function myprompt() { local IFS local nn nb pbits xpwd="" ww=60 len=0 pp='\\w\$ ' local indent uh="${LOGNAME}@${HOSTNAME//.*/}" test -n "$COLUMNS" && let ww=$COLUMNS-20 # may be unset at startup PS1="${_PS1}" if [ ${#PWD} -ge $ww ]; then printf -v indent "%${#uh}s%s" " " "> " # indent strlen(user@host) IFS=/ pbits=( $PWD ); unset IFS nb=${#pbits[*]} for ((nn=1; nn<nb; nn++)) { if [ $(( $len + 1 + ${#pbits[$nn]} )) -gt $ww ]; then xpwd="${xpwd}/...\n${indent}..." len=0 fi xpwd="${xpwd}/${pbits[$nn]}" let len=len+1+${#pbits[$nn]} } # add another newline+indent if the input space is too tight if (( ( ${#uh} + len ) > ww )); then printf -v xpwd "${xpwd}\n%${#uh}s" " " fi PS1="${PS1/$pp/$xpwd}$ " fi } PROMPT_COMMAND=myprompt 

Это работает, беря волшебство \w (соответствует только \w$ для этого) из PS1 и заменяет его $PWD , а затем обертывает его как обычную строку символов. Он пересчитывает PS1 каждый раз из исходного значения, которое сохраняется в _PS1 , это означает, что также сохраняются «невидимые» _PS1 , моя полная строка исходного приглашения для xterm и жирного приглашения:

 PS1="\[\033]0;\u@\h:\w\007\]\[$(tput bold)\]\u@\h\[$(tput sgr0)\]:\w$ " 

И конечный результат – 80 столбцов терминала:

 mr@onomatopoeia:~$ cd /usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace mr@onomatopoeia:/usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/... > .../Perf/Trace$ _ - mr@onomatopoeia:~$ cd /usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace mr@onomatopoeia:/usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/... > .../Perf/Trace$ _ 

Это работает с bash-3.2, поскольку используется printf -v var . Из-за различных сложностей потребуется дополнительная корректировка для других вариантов PS1 .

(Путь в строке заголовка xterm не является ни обернутым, ни сокращенным, что может быть сделано путем включения одного из других ответов здесь в указанную выше функцию.)

В качестве альтернативы, в моем .zshrc я сокращаю первую букву каждого каталога, если ширина пикселя превышает определенную ширину:

 user@machinename:/home/mydirectory1/second_directory user@machinename:/home/mydirectory1/second_directory/my_actual_directory 

будет выглядеть так:

 user@machinename:/h/mydirectory1/second_directory user@machinename:/h/m/s/my_actual_directory 

Вот функция zsh:

  # get the path t=`print -P "%m:%~"`; t=`echo $t | sed -r 's/([^:])[^:]*([0-9][0-9]):|([^:])[^:]*([^:]):/\1\2\3\4:/'`; oldlen=-1; # create 4 buckets of letters by their widths t1="${t//[^ijlIFT]}"; t2="${t//[ijlIFTGoQMmWABEKPSVXYCDHNRUw]}"; t3="${t//[^ABEKPSVXYCDHNRUw]}"; t4="${t//[^GoQMmW]}"; # keep abbreviating parent directories in the path until under 456 pixels while (( ( ( ${#t1} * 150 ) + ( ${#t2} * 178 ) + ( ${#t3} * 190 ) + ( ${#t4} * 201 ) ) > 4560 && ${#t}!=oldlen)) { oldlen=${#t}; t=`echo $t | sed 's/\/\(.\)[^\/][^\/]*\//\/\1\//'`; t1="${t//[^ijlIFT]}"; t2="${t//[ijlIFTGoQMmWABEKPSVXYCDHNRUw]}"; t3="${t//[^ABEKPSVXYCDHNRUw]}"; t4="${t//[^GoQMmW]}"; }; PS1=$t 

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

Это очень удобно, так как он поддерживает контекст, а в zsh позволяет быстро выполнить вкладку с полным каталогом в том же формате. (например, ввод cd /h/m/s/<tab> будет автозаполнен в cd /home/mydirectory1/second_directory )

Попробуйте использовать этот скрипт Python . Он отсекает отдельные разделы имени пути, точно так же, как вы хотели в своем вопросе. Он также использует многоугольник unicode, который занимает только один столбец вместо трех.

Пример вывода для вашего пути (при заданном значении 30 символов):

 /home/mydir…/second…/my_actua… 

Стоит отметить, что это решение правильно обрабатывает Unicode в именах каталогов, используя wcswidth . ${#PWD} , которые использовали другие ответы, будет плохо ошибочно определять визуальную ширину любого пути, содержащего символы UTF-8.

  • «Ls $ PWD» и «ls.» Получают разные файлы, возможно, странное кэширование?
  • копировать файлы из родительского местоположения, когда я внутри символьно связанной папки
  • Почему pwd не обновляется после удаления каталога?
  • Как / где переменные среды хранения оболочки хранятся?
  • cd в исходное местоположение при записи сеанса с командой «script»
  • Помогите мне, пожалуйста, найти мое недоразумение об этом маленьком фрагменте скрипта
  • Как я могу запустить команду в bash после любого изменения в $ PWD?
  • Команда, которая дает имя пользователя @ hostname: pwd
  • PS1 = '$ (pwd)' почему это работает и почему это отличается от PS1 = $ (pwd)
  • Разница между / и //
  • Если процессы не могут изменить среду своего родителя, что делает MC?
  • Как обрезать CWD, показанную в команде promt
  • Interesting Posts

    Как сохранить команду в той же области окна консоли? ( «W»)

    FFmpeg – Разделение нескольких видеофрагментов

    Катить все файлы в папке, включая имя файла, используя цикл for?

    Как построить устройство сетевого подключения?

    Периодическая репликация файловой системы с моментальным снимком

    Копирование содержимого emacs через буфер обмена в терминальном приложении копирует неожиданные вкладки для некоторых пространств

    Почему я не могу избежать пробелов в сценарии bash?

    Grep -line-buffered, могу ли я искать тот же буфер с результатами первого grep?

    Как присоединиться к двум файлам на основе полей с изменением порядка колонок?

    Обратный grep, чтобы получить последние пару вхождений в файл

    Есть ли способ узнать количество строк из вывода команды?

    Bash: `test` находит файл, но` source` wont

    Новая установка Ubuntu, теперь загрузочный экран перезагрузки показывает контроллер Ethernet в течение 1 минуты

    Конфигурация сервера nginx с несколькими местоположениями не работает

    Как только вы монтируете файловую систему, как вы читаете и записываете файлы?

    Linux и Unix - лучшая ОС в мире.