Эквивалент командной строки `getrusage()`

#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 , это позволило бы мне выполнять многозадачность.