Вывод из printf отличается от указанного в аргументе FORMAT

Некоторое описание того, как работает ulimit:

ulimitимеет дело с системными вызовамиsetrlimitи getrlimit. Легко убедиться, чтоstrace-процесс bash(ulimitявляется компонентомbash). Я установил 1024кб изmax memory size:

$ ulimit -m 1024

В другой консоли:

$ strace -p 
...
getrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
setrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
... 

setrlimitсправочная страница написать следующее оRLIMIT_RSS:

RLIMIT_RSS Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.

madviceСистемный вызов — это просто совет ядру, и ядро ​​может игнорировать этот совет. Даже справочная страница bashо ulimitпишет следующее:

-m The maximum resident set size (many systems do not honor this limit)

Вот почему -mне работает.

Об опции -v:

Выставил 1024 кб виртуальной памяти:

$ ulimit -v 1024

В другой консоли:

$ strace -p 
...
getrlimit(RLIMIT_AS, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
setrlimit(RLIMIT_AS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
...

setrlimitсправочная страница написать следующее оRLIMIT_AS:

RLIMIT_AS The maximum size of the process's virtual memory (address space) in bytes. This limit affects calls to brk(2), mmap(2) and mremap(2), which fail with the error ENOMEM upon exceeding this limit. Also automatic stack expansion will fail (and generate a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)). Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited.

Программа состоит из 3 сегментов (данные, код, стек )составляют виртуальную память программы.

  • Сегмент кода является константой и содержит программные инструкции.

  • Сегмент данных управляется следующим:

    Системный вызов

    brkрегулирует размер сегмента данных(части виртуальной памяти )программы.

    mmapСистемный вызов сопоставляет файл или устройство с виртуальной памятью процесса.

    Многие программы выделяют память (прямо или косвенно )путем вызова стандартной функции из библиотеки C (malloc), которая выделяет память из кучи(части сегмента данных ). mallocнастроить размер сегмента данных, вызвав системный вызов brk.

  • Стек хранит переменные функций (переменная занимает память при выделении из стека ).

Вот почему вариант -vвам подходит.

Если -vдостаточно для вашей задачи, то нет причин делать что-то еще и этого достаточно.


Если вы хотите взять под контроль огромное количество конкретных функций памяти для процесса (нехватки памяти, использования подкачки, лимита RSS, OOM и т. д. )я предлагаю вам использоватьпамять cgroupsвозможности.

Если ваше приложение является сервисом, предлагаю вам использоватьвозможности systemd slice , как наиболее удобные для контроля и ограничения ресурсов сервиса или группы сервисов (также его легко настроить вместо того, чтобы настраивать cgroupsнапрямую ), которым управляет systemd.

0
05.04.2020, 19:41
1 ответ

Ваша переменная PWD_HASHсодержит возврат каретки \rв конце строки, которая перемещает последние два символа "}в начало вывода.

Пример:

$ PWD_HASH='{SHA512-CRYPT}abcde'$'\r'
$ PWD_JSON=$(printf '{"password": "%s"}' "$PWD_HASH")
$ echo "$PWD_HASH"
{SHA512-CRYPT}abcde
$ echo "$PWD_JSON"
"}password": "{SHA512-CRYPT}abcde
$ echo "$PWD_JSON" | od -c
0000000   {   "   p   a   s   s   w   o   r   d   "   :       "   {   S
0000020   H   A   5   1   2   -   C   R   Y   P   T   }   a   b   c   d
0000040   e  \r   "   }  \n
0000045
7
28.04.2021, 23:18

Теги

Похожие вопросы