Цикл while удаляет все файлы и зацикливается

Проверьте, существует ли/etc/group-(с тире )в конце. Это резервная копия файла групп.

Я больше знаком с Debian и Red Hat, чем с Arch, но в целом группы настроены:

  • При установке базовой системы.
  • По мере добавления пакетов в систему требуется особое разделение.
  • По мере добавления новых пользователей в систему.

В Debian принудительная переустановка всего пакета позаботится о первых двух экземплярах, а просмотр /homeостальных.

И GID основного пользователя являются четвертым /etc/passwdполем по passwd(5).

Позаботившись об очевидных системных группах, просмотрите /home и, возможно, запустите findпоиск любых GID, которых нет в вашем /etc/groupsфайле. Это будет указывать на любые невосстановленные данные.

Между тем, вы также должны спросить себя:

  1. Почему вы вообще удалили /etc/group?
  2. Почему у вас нет /etcпод контролем версий?
  3. Почему у вас нет резервных копий?

Я бы сосредоточился на решении всех трех проблем.

0
03.01.2020, 01:08
3 ответа

Вот как я бы исправил и улучшил ваш скрипт:

#!/bin/bash

touch while/151234
touch while/152355
touch while/151694
touch while/153699
touch while/156946

NUMSNAPS=$(ls -1 while | wc -l)
RETAIN=2

while (( RETAIN < NUMSNAPS )); do
    OLDEST=$(ls -1t while | tail -n 1)
    rm "while/$OLDEST"
    (( --NUMSNAPS ))
done
0
28.01.2020, 02:29

Но почему нельзя получить весь список и просто оставить нужное количество файлов? Например:

ls -r while | tail -n +${retain} | xargs echo rm
1
28.01.2020, 02:29

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


В оболочке zshвы можете сделать

retain=2

rm -f while/*(DN.Om[retain+1,-1])

для удаления всех обычных файлов (, включая файлы со скрытыми именами ), кроме $retainпоследних измененных файлов. Если это несколько тысяч файлов, вы можете использовать zargsвместо :

.
retain=2

autoload -U zargs
zargs -- while/*(DN.Om[retain+1,-1]) -- rm

Если вместо этого вы хотите упорядочить файлы по имени, заменитеOm(«упорядочить по отметке времени mtime, в порядке убывания» )наOn(«упорядочить по имени, в порядке убывания» ).

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

retain=2

zsh -c 'rm -f $2/*(DN.Om[$1+1,-1])' zsh "$retain" "while"

Это также передает имя каталога и количество сохраняемых файлов в сценарий строки -, что упрощает включение в существующий сценарий, отличный от -zsh.


В оболочке bashвы не хотите анализировать выводls. Вместо этого вы можете использовать

shopt -s dotglob nullglob

retain=2

set -- while/*

while [ "$#" -gt "$retain" ]; do
    rm -f "$1"
    shift
done

Это установит список позиционных параметров в список файлов в каталоге while(, включая скрытые имена ), а затем удалите файлы из этого списка до тех пор, пока в каталоге не останутся только retainфайлы. список.

Это позволяет избежать проблем с неудобными именами файлов, а также позволяет избежать вызова lsодин раз для каждого удаленного файла.

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

1
28.01.2020, 02:29

Теги

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