#bash #command-line #io
#bash #командная строка #io
Вопрос:
Я хотел бы отслеживать операции ввода-вывода с диска, выполняемые данной командой. getrusage()
может использоваться в C; могу ли я как-то получить то же самое в командной строке?
time
и times
показать потраченное пользовательское и системное время, последнее, включая разбивку на собственные / дочерние элементы, как насчет всех остальных битов, таких как дисковый ввод-вывод, spwap, максимальная память?
Пример:
[user@hsot ~]$ time sqlite3 haha.db vacuum
real 1m6.439s
user 0m7.407s
sys 0m10.000s
# what I'd like in addition
blocks in 1228349
blocks out 34523
maxrss 45634953
...
Ответ №1:
В идеале что-то подобное должно быть встроено в bash (или любую другую оболочку, которую вы используете). К сожалению, такой вещи AFAIK не существует.
Но тривиально создать свою собственную оболочку с помощью getrusage ():
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
int main(int argc, char** argv) {
system(argv[1]);
struct rusage ru;
getrusage(RUSAGE_CHILDREN, amp;ru);
printf("nblocks in:t%linblocks out:t%linmaxrss:tt%lin",
ru.ru_inblock, ru.ru_oublock, ru.ru_maxrss);
}
скомпилируйте его:
$ gcc -o process_io process_io.c
И используйте его:
$ ./process_io "dd if=/dev/urandom of=foobar bs=1k count=10000"
10000 0 records in
10000 0 records out
10240000 bytes (10 MB) copied, 0.922149 s, 11.1 MB/s
blocks in: 0
blocks out: 80128
maxrss: 1676
Комментарии:
1. Потрясающе … гарантируется ли значение rusage равным 0 перед
system()
вызовом? Кроме того, учитываются ли «внуки»?2. значение getrusage() равно 0 при создании процесса. system() запускает оболочку, которая сама может выполнять небольшие операции ввода-вывода (чтение файлов конфигурации). Кроме этого, у этого процесса нет других дочерних элементов.
3. Вы могли бы использовать fork() / exec() и waitpid() вместо system(), чтобы избежать небольших накладных расходов оболочки и получить точные результаты.
4. Все еще потрясающе. Все еще работает. Также найдены /usr/bin/time -v для Linux и /usr/bin/time -l для Darwin .
Ответ №2:
После ответа Криса у меня есть это в Python:
#!/usr/bin/env python
import sys
import resource
import subprocess
bsel = resource.getrusage(resource.RUSAGE_SELF)
bchl = resource.getrusage(resource.RUSAGE_CHILDREN)
subprocess.Popen(sys.argv[1:]).communicate()
for i in range(10**7): pass # test children/self independence
asel = resource.getrusage(resource.RUSAGE_SELF)
achl = resource.getrusage(resource.RUSAGE_CHILDREN)
print("""--child--
usert%s
syst%s
memt%s
inbt%s
oubt%s
majt%s
nivcswt%s""" % (achl.ru_utime - bchl.ru_utime,
achl.ru_stime - bchl.ru_stime,
achl.ru_maxrss,
achl.ru_inblock - bchl.ru_inblock,
achl.ru_oublock - bchl.ru_oublock,
achl.ru_majflt - bchl.ru_majflt,
achl.ru_nivcsw - bchl.ru_nivcsw))
print("""--self--
usert%s
syst%s
memt%s
inbt%s
oubt%s
majt%s
nivcswt%s""" % (asel.ru_utime - bsel.ru_utime,
asel.ru_stime - bsel.ru_stime,
asel.ru_maxrss,
asel.ru_inblock - bsel.ru_inblock,
asel.ru_oublock - bsel.ru_oublock,
asel.ru_majflt - bsel.ru_majflt,
asel.ru_nivcsw - bsel.ru_nivcsw))
кажется, это работает 🙂
Постскриптум Я все еще ищу разъяснения для себя против детей против внуков. Новые ответы тоже приветствуются 🙂
Ответ №3:
iostat отображает системную запись / чтение на диски. К сожалению, не для конкретного процесса, а для всей системы, но если вы работаете на своей машине разработки, я думаю, это может быть нормально.
Комментарии:
1. Я использую
iostat
и дажеiotop
. Вы правы, что некоторая информация может быть отображена. В идеале я хотел бы что-то ненавязчивое, напримерtime
, это позволило бы мне выполнять многозадачность.