Почему cron пытается перейти в домашний каталог пользователя и как этого избежать?

Требования

Мне нужен сценарий bash, который создает каталог, названный в честь каждой группы. А затем текстовый файл внутри, названный для каждого человека в этой группе, с соответствующей ссылкой в ​​первой строке.

#!/bin/bash
while read a b
do
    # Skip blank lines
    test -z "$a" && continue

    if [[ "$a" == "Group" ]]
    then
        # Create the group directory
        group_dir="$a $b"
        mkdir "$group_dir"
    else
        # Write the link into the named file
        echo "$a" > "$group_dir/$b"
    fi
done <list.txt

Для пуристов это предполагает ряд ограничений:

  • ни одна строка в вашем текстовом файле не начинается со значительного пробела
  • ссылка не содержит пробелов
  • либо в каждой строке содержится ровно два слова, разделенных пробелом, либо что строки пусты
  • что первая непустая строка является заголовком группы

Все эти предположения можно преодолеть за счет дополнительного кода (и сложности).

1
08.05.2018, 16:35
2 ответа

Когда cronзапустит crontabпользователя, он захочет запуститься в пользовательском домашний каталог. Начальное значение этой переменной взято из/etc/passwd(в простых случаях ). К тому времени, когда вы попытаетесь переопределить HOMEв записи crontab, cronпопытается измениться на ${HOME}.

1
27.01.2020, 23:23

При условии, что документация плохая или неверная, погружение в исходный код:

% rpm -qa | grep cron
cronie-1.4.11-17.el7.x86_64
cronie-anacron-1.4.11-17.el7.x86_64
crontabs-1.11-6.20121102git.el7.noarch

... некоторые латагообингледокидут сюда, так как URL-адрес в RPM не работает...

% git clone https://github.com/cronie-crond/cronie && cd cronie
% fgrep -rl 'chdir failed'.
./src/security.c

... так что ошибка появляется только в одном месте, внутри вызова cron_change_user_permanently, который вызывается из разных других мест в коде...

% grep cron_change_user_permanently **/*.c
src/do_command.c:               if (cron_change_user_permanently(e->pwd, env_get("HOME", jobenv)) < 0)
src/do_command.c:               if (cron_change_user_permanently(e->pwd, env_get("HOME", jobenv)) < 0)
src/popen.c:            if (cron_change_user_permanently(pw, env_get("HOME", jobenv)) != 0)
src/security.c:int cron_change_user_permanently(struct passwd *pw, char *homedir) {

... поэтому во всех случаях переменная среды HOMEиспользуется для определения того, куда chdirдля пользователя, и всегда есть chdirдля этого каталога. Таким образом, вам нужно убедиться, что каталог HOMEсуществует или что HOMEправильно установлен , прежде чемcron_change_user_permanentlyбудет вызван (, что, вероятно, произойдет до того, как код оболочки в вашем задании cron будет даже просмотрен. ). (Или заплатка для обезьяны cronie, чтобы сделать что-то еще, но это, вероятно, действительно очень плохая идея.)

4
27.01.2020, 23:23

Теги

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