Скобки и фигурные скобки не работают должным образом в cron

Жалко, что вы переработали свой вопрос из первой версии, которая касалась setenv(), потому чтоsetenv()имеет утечку памяти, по крайней мере, в реализации glibc.

Возьмите этот пример программы; он будет расти и расти, пока не съест всю память, которую сможет:

#include <stdlib.h>
#include <stdio.h>
int main(void){
        char buf[24];
        for(;;){
                snprintf(buf, sizeof buf, "%d", rand());
                setenv("foo", buf, 1);
        }
}

В реализации glibc setenv()никогда не будет освобождаться память, уже выделенная предыдущим setenv(); однако он будет избегать дублирования, отслеживая строки среды, выделенные им в двоичном дереве (с использованием tfind(3), отдельно от списка char **environ). Это также дает хороший эффект сокрытия утечки от таких инструментов, как valgrind;-)


Что касается putenv(), он полагается на то, что вызывающий объект управляет строкой, переданной ему в качестве аргумента. Таким образом, задача вызывающей стороны состоит в том, чтобы убедиться, что она не пропустит его при повторном вызове putenv(), что он не освободит его, пока он все еще является частью среды, и что он не использует для этого автоматическую/стековую переменную.

Кроме того, изменение строки после вызова putenv()может привести к удалению переменной среды или добавлению другой. Пример:

#define _XOPEN_SOURCE   500
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <unistd.h>
int main(void){
        extern char **environ;
        static char *my_environ[] = { "YUCK=yumm", 0 };
        static char str[256] = "FOO=bar";
        environ = my_environ;
        putenv(str);
        snprintf(str, sizeof str, "BAZ=quux");
        execl("/usr/bin/printenv", "printenv", (void*)0);
        err(1, "execlp");
}

Это требуется по стандарту, но не работало в старых версиях glibc, где putenv()делал копию своего аргумента.


Наконец, и setenv(), и putenv()будут перемещать массив char **environпри добавлении новой переменной в среду.Реализация сохранит свою собственную копию указателя и увеличит ее с помощью realloc(), но не будет возиться со своим исходным (, который указывает на статическую память ), или с памятью, выделенной вручную, например. environ = calloc(sizeof *environ, envlen).

0
16.09.2021, 19:42
1 ответ

@steeldriver был прав. Я использовал неправильный формат, так как /etc/crontab отличается от crontab пользователя root (, который не содержит поля who ).

1
16.09.2021, 21:55

Теги

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