Вы можете попробовать пакет pm-utils
для куча команд управления питанием. Это:
pm-hibernate pm-powersave pm-suspend-hybrid
pm-is-supported pm-suspend
Что касается блокировки, в репозитории есть пакет xscreensaver
. Вы можете попробовать.
Проблема в том, что эти /proc
файлы в Linux выглядят как текстовые файлы, что касается stat()/fstat()
, но не ведут себя как таковые.
Поскольку это динамические данные, вы можете выполнить только один системный вызов read()
для них (по крайней мере, для некоторых из них). Если сделать больше одного, то можно получить два куска с разным содержимым, так что вместо этого, похоже, второй read()
на них просто ничего не вернет (что означает конец файла) (если только вы не lseek()
вернетесь к началу (и только к началу)).
Утилита read
должна читать содержимое файлов по одному байту за раз, чтобы быть уверенной, что не прочтет больше символа новой строки. Вот что делает dash
:
$ strace -fe read dash -c 'read a < /proc/sys/fs/file-max'
read(0, "1", 1) = 1
read(0, "", 1) = 0
Некоторые оболочки, такие как bash
, имеют оптимизацию, чтобы избежать необходимости выполнять много системных вызовов read()
. Сначала они проверяют, является ли файл искомым, и если да, то читают кусками, так как тогда они знают, что могут вернуть курсор обратно сразу после новой строки, если они прочитали мимо нее:
$ strace -e lseek,read bash -c 'read a' < /proc/sys/fs/file-max
lseek(0, 0, SEEK_CUR) = 0
read(0, "1628689\n", 128) = 8
С bash
у вас все еще будут проблемы для файлов proc размером более 128 байт, которые можно прочитать только за один системный вызов read.
bash
также, похоже, отключает эту оптимизацию при использовании опции -d
.
ksh93
заводит оптимизацию еще дальше, настолько, что она становится фальшивой. read
ksh93 выполняет поиск назад, но запоминает дополнительные данные, которые он прочитал, для следующего read
, поэтому следующий read
(или любой другой его встроенный модуль, читающий данные, например cat
или head
) даже не пытается read
данные (даже если эти данные были изменены другими командами в промежутке):
$ seq 10 > a; ksh -c 'read a; echo test > a; read b; echo "$a $b"' < a
1 2
$ seq 10 > a; sh -c 'read a; echo test > a; read b; echo "$a $b"' < a
1 st
На первый взгляд, это похоже на ошибку в оболочках, которые возвращают меньше, чем возвращает настоящий Bourne Shell или его производные (sh, bosh, ksh, heirloom).
Оригинальный Bourne Shell пытается прочитать блок (64 байта) Более новые варианты Bourne Shell читают 128 байт, но они начинают читать заново, если нет нового символа строки.
Предыстория: /procfs и подобные реализации (например, смонтированный /etc/mtab
виртуальный файл) имеют динамическое содержимое, и вызов stat()
не вызывает повторного создания динамического содержимого первым. По этой причине размер такого файла (с момента чтения до EOF) может отличаться от того, что возвращает stat()
.
Учитывая, что стандарт POSIX требует, чтобы утилиты ожидали коротких чтений в любое время, программы, которые считают, что read()
, возвращающий меньше, чем заказанное количество байт, является признаком EOF, нарушены. Правильно реализованная утилита вызывает read()
второй раз в случае, если она возвращает меньше, чем ожидалось - пока не будет возвращен 0. В случае встроенной утилиты read
, конечно, достаточно читать до EOF
или , пока не появится NL
.
Если вы запустите truss
или клон truss, вы сможете убедиться в некорректном поведении оболочек, которые возвращают только 6
в вашем эксперименте.
В этом особом случае, похоже, это ошибка ядра Linux, см.:
$ sdd -debug bs=1 if= /proc/sys/fs/file-max
Simple copy ...
readbuf (3, 12AC000, 1) = 1
writebuf (1, 12AC000, 1)
8readbuf (3, 12AC000, 1) = 0
sdd: Read 1 records + 0 bytes (total of 1 bytes = 0.00k).
sdd: Wrote 1 records + 0 bytes (total of 1 bytes = 0.00k).
Ядро Linux возвращает 0 при втором read
, и это, конечно, неправильно.
Заключение: Оболочки, которые сначала пытаются прочитать достаточно большой кусок данных, не вызывают эту ошибку ядра Linux.
В файлах под /proc иногда используется символ NULL для разделения полей внутри файла. Похоже, что read не в состоянии обработать это.
Если вам интересно узнать, почему? это так, то вы можете посмотреть ответ на этот вопрос ответ в исходниках ядра здесь:
if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
*lenp = 0;
return 0;
}
В основном, поиск (*ppos
не 0) не реализован для чтения (!write
)
значений sysctl, которые являются числами. Всякий раз, когда выполняется чтение из /proc/sys/fs/file-max
,
рассматриваемая процедура
__do_proc_doulongvec_minmax()
вызывается из записи для file-max
в
конфигурационной таблице в
том же файле.
Другие записи, такие как /proc/sys/kernel/poweroff_cmd
, реализуются через
proc_dostring()
, которая разрешает поиск, так что вы можете сделать dd bs=1
на ней и читать из оболочки без проблем.
Обратите внимание, что начиная с ядра 2.6 большинство /proc
чтений было реализовано через новый API
под названием
seq_file
и он поддерживает seeks, так что чтение /proc/stat
не должно вызывать проблем.
проблем. Реализация /proc/sys/
, как мы видим, не использует этот
api.