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