Можно проследить системные вызовы с strace
, но существует действительно неизбежный штраф скорости. Необходимо работать strace
как базируются, если команда работает с поднятыми полномочиями:
sudo strace -f -o foo.trace su user -c 'mycommand'
Другой метод это, вероятно, будет быстрее, должен предварительно загрузить библиотеку, которая переносит функции доступа к файловой системе: LD_PRELOAD=/path/to/libmywrapper.so mycommand
. LD_PRELOAD
переменная среды не будет передана программам, вызванным с поднятыми полномочиями. Необходимо было бы написать код той библиотеки-оболочки (вот пример от “Создания переходников библиотеки для забавы и прибыли”); я не знаю, существует ли имеющийся в сети повторно используемый код.
При контроле файлов в конкретной иерархии каталогов можно сделать представление файловой системы с LoggedFS таким образом, что все доступы посредством того представления зарегистрированы.
loggedfs -c my-loggedfs.xml /logged-view
mycommand /logged-view/somedir
Для конфигурирования LoggedFS запустите с демонстрационной конфигурации, поставленной с программой, и считайте синтаксис конфигурационного файла LoggedFS.
Другая возможность является контрольной подсистемой Linux. Удостоверьтесь auditd
демон запускается, затем настройте то, с чем Вы хотите зарегистрироваться auditctl
. Каждая зарегистрированная операция зарегистрирована в /var/log/audit/audit.log
(на типичных дистрибутивах). Начинать наблюдать конкретный файл:
auditctl -a exit,always -w /path/to/file
При помещении часов на каталог за файлами в нем и его подкаталогах рекурсивно также наблюдают. Заботьтесь для не наблюдения каталога, содержащего контрольные журналы. Можно ограничить вход определенными процессами, видеть auditctl
страница справочника для доступных фильтров. Необходимо быть корнем для использования системы аудитов.
Awk (также проверяют Информацию Awk) красив с таким вопросом. Попробуйте:
awk -F'[],] *' '{print $2}' cities
Это определяет разделителя полей -F
как [],] *
- что означает одно происшествие или заключительной квадратной скобки или запятой, сопровождаемой нулем или любым количеством пробелов. Конечно, можно изменить это для удовлетворения любому требованию. Читайте на регулярных выражениях.
После того как строка разделяется, можно сделать то, что Вы хотите с результатом разделения. Здесь, я решил распечатать второе поле только с print $2
. Обратите внимание, что важно использовать одинарные кавычки вокруг awk инструкций иначе, 2$ заменяет оболочка.
Можно изменить последнее cut
в Вашем конвейере к этому:
cut -d ' ' -f2-
Вышеупомянутые средства, что разделитель полей является пробелом, и мы хотим выбрать все поля, начинающие со второго. Полная последовательность становится:
cut -d ',' -f1 cities | cut -d ' ' -f2-
Для более сложного парсинга необходимо использовать sed (1):
sed -e 's/\[[0-9]\+\] \([^,]\+\),.*/\1/' cities
Или использование -r
упростить регулярное выражение, как предложено pepoluan:
sed -re 's/\[[0-9]+\] ([^,]+),.*/\1/' cities
Я обычно использую Perl, когда вещи становятся слишком трудными для sed и grep.
Существует много способов, которыми Вы могли записать это в Perl. Например, Вы могли бы предпочесть, чтобы это было быстро, или Вы могли бы предпочесть, чтобы это решило небольшие неожиданные проблемы во входе (например, два пробелов, где каждый ожидался).
Один очевидный путь (принимает идентификатор, является числовым, город является алфавитным, состояние является алфавитным):
while (<>) {
if (/^\[\d+\] (\w+(?: \w+)*), \w+ \(\w*\)$/) {
my $city = $1;
print "$city\n";
}
}
Или медленнее но более разрешающий (делает больше отслеживания в обратном порядке):
while (<>) {
if (/^.*\]\s+(.*),.*$/) {
my $city = $1;
print "$city\n";
}
}
Или быстрее (поле останавливается в первом вхождении закрывающей скобки):
while (<>) {
if (/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/) {
my $city = $1;
print "$city\n";
}
}
Из командной строки, а не сценария, Вы могли использовать -n
опция, которая в основном добавляет while (<>) { BLOCK }
цикл:
perl -ne '/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/ and print $1, "\n";' cities
или если Вы хотите, чтобы использование напомнило сокращение, можно использовать -F
опция, которая подобна awk's -F
опция, например:
perl -a -n -F'/[],]\s+/' -e 'print $F[1], "\n"' cities
Таким образом, очевидно, предполагает, что никакое поле не будет содержать ни одного из разделителей.
]
не угловая скобка. Угловые скобки<>
.[]
"квадратные скобки" или просто "скобки". – cjm 22.04.2011, 21:54