Как освободить место в /usr

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

В разделе Списки команд руководства Bash ( спасибо jimmij ) говорится:

Если команда завершается управляющим оператором '&', оболочка выполняет { {1}} команда асинхронно в подоболочке. Это называется выполнением команды в фоне . Оболочка не ждет, пока команда завершится , и статус возврата - 0 (истина).

Насколько я понимаю, когда вы запускаете sleep 10 и shell fork s для создания нового дочернего процесса (его копии), а затем немедленно exec , чтобы заменить этот дочерний процесс кодом из внешней команды ( sleep ). Это похоже на то, что происходит, когда команда выполняется в обычном режиме (на переднем плане). См. Статью в Википедии Fork – exec для краткого обзора этого механизма.

Я не мог понять, почему Bash запускает фоновые команды в подоболочке, но это имеет смысл, если вы также хотите иметь возможность запускать встроенные команды оболочки, такие как exit или echo для работать в фоновом режиме (а не только внешними командами).

Когда встроенная оболочка запускается в фоновом режиме, форк происходит (в результате получается подоболочка) без вызова exec для замены себя внешней командой. Выполнение следующих команд показывает, что когда команда echo заключена в фигурные скобки и выполняется в фоновом режиме (с помощью & ), подоболочка действительно создается:

$ { echo $BASH_SUBSHELL $BASHPID; }
0 21516
$ { echo $BASH_SUBSHELL $BASHPID; } &
[1] 22064
$ 1 22064

например, я заключил команду echo в фигурные скобки, чтобы избежать расширения BASH_SUBSHELL текущей оболочкой; фигурные скобки используются для группировки команд без использования подоболочки. Вторая версия команды (заканчивающаяся управляющим оператором & ) ясно демонстрирует, что завершение команды амперсандом привело к созданию подоболочки (с новым PID) для выполнения echo встроенный. (Я, вероятно, здесь упрощаю поведение оболочки. См. Комментарий mikeserv.)

Я бы никогда не подумал запустить exit & , и если бы я не прочитал ваш вопрос, я бы ожидал, что текущая оболочка для выхода. Теперь, когда вы знаете, что такие команды выполняются в подоболочке, ваше объяснение, что выходит именно из подоболочки, имеет смысл.


«Почему подоболочка, созданная оператором управления фоном (&), не отображается в pstree»

Как упоминалось выше, когда вы запускаете sleep 10 & , Bash разветвляется для создания подоболочки, но поскольку sleep - внешняя команда, она вызывает системный вызов exec () , который немедленно заменяет код Bash и данные в дочернем процессе на работающую копию sleep программа. К тому времени, когда вы запустите pstree , вызов exec уже будет завершен, и теперь дочерний процесс будет иметь имя « sleep ».


Находясь вдали от своего компьютера, я попытался придумать способ поддерживать подоболочку в работе достаточно долго, чтобы подоболочка отображалась pstree . Я решил, что мы можем запустить команду через time builtin:

$ time sleep 11 &
[2] 4502
$ pstree -p 26793
bash(26793)─┬─bash(4502)───sleep(4503)
            └─pstree(4504)

Здесь оболочка Bash (26793) разветвляется для создания подоболочки (4502) для выполнения команды в фоновом режиме. Эта подоболочка запускает собственную встроенную команду time , которая, в свою очередь, выполняет ветвление (для создания нового процесса с PID 4503) и запускает внешнюю команду sleep .


Используя именованные каналы , jimmij придумал хитрый способ поддерживать подоболочку, созданную для запуска exit , достаточно долго, чтобы она отображалась pstree :

$ mkfifo file
$ exit  file
$ jobs
[2]-  Done    exit < file

Перенаправление stdin из именованного канала является разумным, поскольку оно заставляет подоболочку блокироваться до тех пор, пока она не получит входные данные из именованного канала.Позже, перенаправление вывода echo (без каких-либо аргументов) записывает символ новой строки в именованный канал, который разблокирует процесс подоболочки, который, в свою очередь, запускает встроенную команду exit .


Аналогично для команды sleep :

$ mkfifo named_pipe
$ sleep 11 < named_pipe &
[1] 6600
$ pstree -p 26793
bash(26793)─┬─bash(6600)
            └─pstree(6603)

Здесь мы видим, что подоболочка, созданная для выполнения команды в фоновом режиме, имеет PID 6600 . Затем мы разблокируем процесс, записывая символ новой строки в конвейер:

$ echo > named_pipe

подоболочка, затем exec s для выполнения команды sleep .

$ pstree -p 26793
bash(26793)─┬─pstree(6607)
            └─sleep(6600)

После вызова exec () мы видим, что дочерний процесс ( 6600 )теперь работает программа сна .

1
18.10.2018, 09:16
3 ответа

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

Я заметил, что ваш корневой раздел

root@debian:/home/midhun# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda11       91G   11G   76G  12% /

имеет много свободного места, а /usrполностью закончилось.

Вот как я подхожу к этой задаче -вам нужно будет загрузиться с live CD/USB flash, чтобы сделать следующее:

  1. Удалить или закомментировать запись /usrиз/etc/fstab
  2. umount /usr/local(на всякий случай)
  3. cp -a --preserve=all /usr /usr-new
  4. umount /usr
  5. rmdir /usr
  6. mv /usr-new /usr

В качестве альтернативы вы можете запустить sudo du -x /usr | sort -n | tail -30и посмотреть, какие каталоги занимают больше всего места.

Затем используйте sudo dpkg-query -S /path, чтобы узнать, к каким пакетам они принадлежат, и удалите их с помощью sudo apt remove packagename.

2
26.06.2020, 13:08

Вы уже сделали это, смонтировав свободный диск/раздел (/dev/sda16 )в /usr/local. Вы можете сделать то же самое с другими «большими» каталогами, но, пожалуйста, убедитесь, что вы понимаете разветвления, поскольку это усложняет работу и может оставить систему в затруднительном состоянии.

0
28.01.2020, 02:11

сначала запустите это, чтобы определить самые большие каталоги в вашей системе

sudo du -k / | sort -n|tail -222

затем rmуказать оскорбительные каталоги в /home

вы можете просто сфокусироваться напрямую, используя

sudo du -k /home | sort -n|tail -222
sudo du -k /usr  | sort -n|tail -222

это покажет большие пакеты

dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n

Если вы видите некоторые из них, которые вы недавно установили и/или знаете, что не используете, они являются кандидатами на удаление

Другой способ — просмотреть недавно установленные пакеты, выполнив

grep " install " /var/log/dpkg.log

, чтобы узнать, не являются ли какие-либо из них необязательными и могут быть удалены

Избегайте прямого удаления чего-либо в /usr, так как он содержит важные системные инструменты, удаление которых может привести к повреждению системы. Вместо этого определите необязательные пакеты, а затем используйте обычные команды для удаления этих пакетов-кандидатов.

sudo apt remove  unused-big-package    
sudo apt purge   unused-big-package # this also removes its configs
-1
28.01.2020, 02:11

Теги

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