Могу ли я сказать, когда мне был предоставлен доступ sudo?

Не размещайте закрытые ключи в системе. Пользователи могут использовать, например, SSH Agent forwarding и хранить ключи на своих рабочих станциях. Или использовать аппаратный модуль безопасности (HSM), например, смарт-карту (когда аппаратное обеспечение не позволяет копировать ключи). Оба варианта не позволяют ничему в системе (включая root) копировать ключи, но root может использовать их, когда HSM подключен. Конечно, можно использовать HSM с вторичной аутентификацией (например, вводить PIN-код с клавиатуры на самом HSM при каждом использовании ключа).

Без SELinux или аналогичной системы root может делать в системе все, что угодно - читать/писать любые файлы, делать дамп памяти любого процесса и т.д.

1
31.01.2019, 23:20
1 ответ

Использование print >filenameв awkоткроет файл и урежет его длину до нуля, если он существует. Затем awkбудет держать файл открытым до конца программы. Если вы сделаете это для многих файлов, вы столкнетесь с ограничениями ресурсов, как вы заметили.

Вам нужно close(filename). В вашем случае close("subfolder/"$1). Вам нужно будет сделать это, пока $1все еще имеет правильное значение.

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

Чтобы обойти это, используйте print >>вместо print >. Это откроет файл для добавления .

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

Полный скрипт может выглядеть примерно так

#!/bin/sh

rm -rf subfolder   # remove old output files 
mkdir subfolder    # and recreate output directory

awk -F '\t' '{ fname = "subfolder/" $1; print >>fname; close(fname) }' inputfile

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

awk -F '\t' '
    fname != "subfolder/" $1 {
        if (fname != "")
            close(fname)
        fname = "subfolder/" $1
    }
    { print >>fname }' inputfile

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


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

Вы можете сделать это, явно проверив, что значение содержит только, например,. строчные или прописные буквенно-цифровые символы (и подчеркивание):

awk -F '\t' '
    fname != "subfolder/" $1 {
        if (fname != "")
            close(fname)
        fname = "subfolder/" $1

        if (fname ~ /[^a-zA-Z0-9_]/) {
            print "Bad filename: " fname >"/dev/stderr"
            exit(1)
        }
    }
    { print >>fname }' inputfile

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

.
    {
        if (names[fname]++)
            print >>fname
         else
            print >fname
    }
2
27.01.2020, 23:31

Теги

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