Как перейти от дочерних каталогов к корневому?

То, что вы предлагаете, практически невозможно выполнить стандартными средствами.

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

Мы могли бы создать новую оболочку с обязательным ведением журнала команд, чтобы предотвратить это (с отправкой журналов в другой процесс через конвейер, сокет или системный журнал), но пользователь все равно мог бы просто запустить обычную оболочку или интерпретатор Perl или Python среди прочего, чтобы обойти ведение журнала. Для регистрации того, что делали подпроцессы, потребуется обернуть весь сеанс в скрипт или что-то подобное, чтобы регистрировать все, что видит пользователь. Даже в этом случае есть возможность просто загрузить код и запустить его, не выводя его на терминал. Запрещение пользователю запускать произвольные программы сделало бы это, но также помешало бы делать самые полезные вещи. Предотвращение запуска оболочек или сценариев Perl также может помешать работе многих распространенных инструментов.

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

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

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

3
17.04.2017, 16:01
2 ответа

Рекурсия вверх до достижения / и вызов функции для каждого каталога.

#!/bin/sh

function mangleperms {
    echo DEBUG would chmod 755 "$1"
}

function walktoroot {
    DIR="$1"
    HANDLE="$2"
    if [ "$DIR" = "/" ]; then
        return
    fi
    "$HANDLE" "$DIR"

    # recursion (noun): see recursion
    PARENTDIR=`dirname "$DIR"`
    walktoroot "$PARENTDIR" "$HANDLE"
}

if [ -z "$1" ]; then
    echo >&2 "Usage: walktoroot dir"
    exit 1
fi
# TODO probably more edge cases on relative dirs, though there are means
# to fully qualify those
if [ "$1" = "." ]; then
    DIR=`pwd`
else
    DIR=$1
fi

walktoroot "$DIR" mangleperms

Например.

$ pwd
/var/tmp/a/b/c
$ /home/jdoe/walktoroot .
DEBUG would chmod 755 /var/tmp/a/b/c
DEBUG would chmod 755 /var/tmp/a/b
DEBUG would chmod 755 /var/tmp/a
DEBUG would chmod 755 /var/tmp
DEBUG would chmod 755 /var
$ 
1
27.01.2020, 21:25

С помощью find мы можем сделать это следующим образом:

find /path/to/dir -type d -prune -exec chmod 755 {} \; -exec sh -c '
   while { set -- "${1%/*}"; case $1 in "" ) break ;; esac; }
   do find "$1" -type d -prune -exec chmod 755 \{\} \;; done
' {} {} \;

Другой метод, использующий рекурсивную функцию :

   fx() {
      case $1 in ?* ) chmod 755 "$1"; fx "${1%/*}" ;; esac
   }
   # and then...
   fx /path/to/dir
​​
1
27.01.2020, 21:25

Теги

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