Как сократить текущий путь к каталогу, отображаемый на терминале?

Зависит от того, что вы подразумеваете под размером .

size=$(wc -c < "$file")

даст вам количество байтов, которое можно прочитать из файла. IOW, это размер содержимого файла. Однако он будет читать содержимое файла (кроме случаев, когда файл является обычным файлом или символической ссылкой на обычный файл в большинстве реализаций wc в целях оптимизации). Это может иметь побочные эффекты. Например, для именованного канала то, что было прочитано, больше не может быть прочитано снова, а для таких вещей, как / dev / zero или / dev / random , которые имеют бесконечный размер, это займет некоторое время. Это также означает, что вам необходимо разрешение на чтение файла, и отметка времени последнего доступа файла может быть обновлена.

Это стандартно и переносимо, однако обратите внимание, что некоторые реализации wc могут включать начальные пробелы в этом выводе.Один из способов избавиться от них - использовать:

size=$(($(wc -c < "$file")))

или избежать ошибки, связанной с пустым арифметическим выражением в тире или yash , когда wc не дает вывод (например, когда файл не открывается):

size=$(($(wc -c < "$file") +0))

ksh93 имеет встроенный wc (если вы его включили, вы также можете вызвать его как команду / opt / ast / bin / wc ), что делает его наиболее эффективным для обычных файлов в этой оболочке.

В различных системах есть команда stat , которая является интерфейсом для системных вызовов stat () или lstat () .

Они сообщают информацию, найденную в индексном дескрипторе. Одной из этих сведений является атрибут st_size . Для обычных файлов это размер содержимого (сколько данных может быть прочитано из него при отсутствии ошибки (это то, что большинство реализаций wc -c используют при оптимизации)). Для символических ссылок это размер целевого пути в байтах. Для именованных каналов, в зависимости от системы, это либо 0, либо количество байтов, находящихся в данный момент в буфере канала. То же самое для блочных устройств, где в зависимости от системы вы получаете 0 или размер в байтах базового хранилища.

Вам не нужно разрешение на чтение файла, чтобы получить эту информацию, только разрешение на поиск в каталоге, с которым он связан.

В хронологическом порядке:

  • IRIX stat (90-е):

     stat -qLs - "$ file" 
     

    возвращает st_size атрибут $ file ( lstat () ) или:

     stat -s - "$ file" 
     

    то же самое, за исключением случаев, когда $ file - это символическая ссылка, в этом случае это st_size файла после разрешения символической ссылки.

  • zsh stat встроенный (теперь также известный как zstat ) в модуле zsh / stat (загружается с zmodload zsh / stat ) (1997):

     стат -L + размер -$ file # st_size файла 
    stat + size - $ file # после разрешения символической ссылки 
     

    или для сохранения в переменной:

     stat -L -A size + size - $ file 
     

    очевидно, самый эффективный в этой оболочке.

  • GNU stat (2001); также в BusyBox stat с 2005 г. (скопировано из GNU stat ):

     stat -c% s - "$ file" # st_size файла 
    stat - Lc% s - "$ file" # после разрешения символической ссылки 
     

    (обратите внимание, что значение -L перевернуто по сравнению с IRIX или zsh stat ].

  • BSD stat (2002):

     stat -f% z - "$ file" # st_size файла 
    stat -Lf% z - "$ file "# после разрешения символической ссылки 
     

Или вы можете использовать функцию stat () / lstat () какого-нибудь языка сценариев, например perl :

perl -le 'print((lstat shift)[7])' -- "$file"

AIX также имеет команду istat , которая сбрасывает все stat () (не lstat () , поэтому работать не будет по символическим ссылкам), с которой вы можете постобработать, например:

LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'

(спасибо @JeffSchaller за помощь в выяснении деталей ).

В tcsh :

@ size = -Z $file:q

(размер после разрешения символической ссылки)

Задолго до GNU int создал свою команду stat , то же самое может быть достигнуто с помощью команды GNU find с ее предикатом -printf (уже в 1991 году):

find -- "$file" -prune -printf '%s\n'    # st_size of file
find -L -- "$file" -prune -printf '%s\n' # after symlink resolution

Однако есть одна проблема: это не работает, если $ file начинается с - или является предикатом find (например, ! , ( ...).

Стандартная команда для получения информации stat () / lstat () - ls .

В соответствии с POSIX вы можете сделать:

LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'

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

Для блочных устройств системы, в которых stat () возвращает 0 для st_size , обычно имеют другие API для сообщения размера блочного устройства. Например, в Linux есть BLKGETSIZE64 ioctl () , и большинство дистрибутивов Linux теперь поставляются с командой blockdev , которая может ее использовать:

blockdev --getsize64 -- "$device_file"

Однако вам нужно для этого разрешение на чтение файла устройства. Обычно можно получить размер другими способами. Например (все еще в Linux):

lsblk -bdno size -- "$device_file"

Должно работать, кроме пустых устройств.

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

  • С помощью zsh (после загрузки модуля zsh / system ):

     {sysseek -w end 0 && size = $ ((systell (0)))} 
  • С ksh93 :

     

    или

     {size = $ (
  • с perl :

     perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN '

Мы видели, что для именованных каналов некоторые системы (по крайней мере, AIX, Solaris, HP / UX) делают объем данных в буфере канала доступным в stat () st_size . Некоторые (например, Linux или FreeBSD) этого не делают.

По крайней мере, в Linux вы можете использовать FIONREAD ioctl () после открытия канала (в режиме чтения + записи, чтобы избежать зависания):

fuser -s -- "$fifo_file" && 
  perl -le 'require "sys/ioctl.ph";
            ioctl(STDIN, &FIONREAD, $n) or die$!;
            print unpack "L", $n' <> "$fifo_file"

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

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

Другой атрибут inode, возвращаемый функцией stat () , - это st_blocks . Это количество блоков по 512 байт, которые используются для хранения данных файла (а иногда и некоторых его метаданных, таких как расширенные атрибуты файловых систем ext4 в Linux). Это не включает сам индексный дескриптор или записи в каталогах, с которыми связан файл.

Размер и использование диска не обязательно тесно связаны, так как сжатие, разреженность (иногда некоторые метаданные), дополнительная инфраструктура, такая как косвенные блоки в некоторых файловых системах, влияют на последнее.

Обычно это то, что du использует для сообщения об использовании диска. Большинство команд, перечисленных выше, смогут получить эту информацию.

  • POSIXLY_CORRECT = 1 ls -sd - "$ file" | awk '{print $ 1; exit} '
  • POSIXLY_CORRECT = 1 du -s - "$ file" (не для каталогов, где это будет включать использование диска файлами внутри).
  • GNU find - "$ file" -printf '% b \ n'
  • zstat -L + block - $ file
  • GNU stat -c% b - "$ file"
  • BSD stat -f% b - - "$ file"
  • perl -le 'print ((lstat shift) [12])' - "$ file"

17
22.07.2017, 16:34
5 ответов

Вам необходимо изменить PS1в файле запуска вашей оболочки (, вероятно,.bashrc).

Если он уже есть, его настройка будет содержать \w, что дает ваш рабочий каталог. Измените это на\W(в верхнем регистре ). Строка в файле bashrcвыглядит следующим образом:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '

Выйдите из системы и снова войдите или выполните:

..bashrc

или (вам нужно добавить этот префикс '~/', если вы находитесь в другом каталоге)

source ~/.bashrc

(или что там у вас за файл ).

Если его нет, добавьте что-то вроде:

PS1='\u@\h: \W:\$'

до .bashrcили что-то еще. Найдите PS1на странице руководства bash, чтобы получить больше идей.

Будь осторожен; bashможет использовать несколько больше, чем один файл инициализации, например. .bashrcи .bash_profile; возможно, PS1установлен в системе -. Но вы можете переопределить это в одном из ваших собственных файлов.

41
27.01.2020, 19:46

в этом случае вам придется редактировать PS1 ,

вместо \wу вас будет команда или переменная, которая показывает сокращенный путь:

оригинальный PS1

PS1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$'

измените его на

PS1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]${PWD##*/}\[\033[00m\]\$'

Обратите внимание, что это поместит имя пользователя вместо ~, если вы находитесь в своем домашнем каталоге!

, чтобы избежать этого, вам понадобится несколько команд вместо ${PWD ##*/}, например.

if [[ "${PWD}" == "${HOME}" ]] ; then printf \~; else echo -n ${PWD##*/}; fi

Новая PS1 будет выглядеть следующим образом

PS1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]`if [[ "${PWD}" == "${HOME}" ]] ; then printf \~; else echo -n ${PWD##*/}; fi`\[\033[00m\]\$'

упс пока я пытался спасти мир, у меня не было идей|забыл \W

1
27.01.2020, 19:46

Предполагая, что вы используете bash, измените строку приглашения (переменную PS1 )так, чтобы она имела \Wвместо \w.

напр. если ваш PS1 в настоящее время \u@\h:\w\$, установите его на\u@\h:\W\$

Чтобы сделать это постоянным, вам придется изменить его в файлах запуска bash -, например. ~/.bash_profileили ~/.bashrc.

см. man bashи найдите PROMPTINGдля получения полной информации и списка экранированных специальных символов с обратной косой чертой -.

4
27.01.2020, 19:46

Начиная с bash 4, для сокращения глубины каталога в строке команды -используется PROMPT_DIRTRIMв файле .bashrc. Просто не забудьте снова открыть терминал.

PROMPT_DIRTRIM=1

Дополнительную информацию см. в Руководстве Bash .

Пример

bob@bob-ubuntu:~/Desktop/Dropbox/School/2017/C/A3/$

будет обрезано до

bob@bob-ubuntu:.../A3/$

75
27.01.2020, 19:46

https://github.com/chrissound/SodiumSierraStrawberry

Позволяет обрезать путь, например:

From: /home/sodium/Projects/Personal/Sierra/Super/Long/Path/HolyAvacado

To: »Projects/Sie…/Sup…/Lon…/Pat…/HolyAvacado/

0
27.01.2020, 19:46

Теги

Похожие вопросы