Похоже, что ресурс exec
puppet ищет команду только в текущем каталоге.
Добавление пути к команде chage
решило проблему
$ which chage
/usr/bin/chage
Итак, объявление ресурса exec выглядит следующим образом
exec {
'chage':
path => '/usr/bin/',
command => 'chage -d 0 askar',
}
Убедился, что пароль пользователя истек, что означает, что пользователь должен сменить пароль при следующем входе.
# chage -l askar
Last password change : Password must be changed
Password expires : Password must be changed
Password inactive : password must be changed
Account expires : Mar 22, 2016
Minimum number of days between password change : 30
Maximum number of days between password change : 60
Number of days of warning before password expires : 7
Самый простой способ получить список пользователей, которые не входили в систему за последние 15 дней, вместо того, чтобы получать его из / home
использует команду lastlog
lastlog -b 15
Просмотр строки вывода:
alumno1 pts / 14 172.17.1.114 Сб, 22 октября 22:18:57 +0100 2016
Если вам просто нужно имя (1-е поле):
lastlog -b 15 | sed "1d" | awk ' { print $1 } '
( sed "1d"
если для удаления заголовка lastlog
)
From man lastlog :
ОПЦИИ К команде lastlog применяются следующие параметры:
-b, --before DAYS Печатать только записи lastlog старше, чем DAYS.
Если пользователь никогда не входил в систему, вместо порта и времени будет отображаться сообщение ** Никогда не входил **.
Что касается фактического скрипта для проверки группы:
#!/bin/bash
getent group alumnos > /dev/null
if [ $? -ne 0 ]
then
echo "group alumnos does not exist"
exit 1
fi
for i in ` lastlog -b 15 | sed "1d" | awk ' { print $1 } '`
do
if [ `id -ng $i` == "alumnos" ]
then
echo $i
fi
done
exit 0
где:
переменная i
будет перебирать имена всех пользователей, указанные в lastlog
id -ng user
дает имя группы пользователя, на которую указывает текущая итерация «$ i», чтобы
выпускники группы getent
проверяли наличие группы
Что касается упомянутой вами ошибки if
; когда grep
ничего не находит, он пропускает операнд и затем становится пустым; отсюда и ошибка.Один из приемов заключается в выполнении сравнения строк с дополнением «x», как в:
if [ "x"$i == "xstring" ]
then
...
Другая альтернатива проверке существования групповых выпускников:
if [ $(grep "^alumnos:" /etc/group) -e ]
then
echo "No group alumnos"
exit 1
fi
Еще одна альтернатива для проверки наличия пользователя с несколькими группами:
groups user | grep alumnos
Если вы хотите перечислить пользователей, которые принадлежат к дополнительной группе foo
, используйте
getent group foo | cut -d ':' -f 4- | tr -s '\n,' '\n\n'
Команда getent
использует " переключатель службы имен "; это означает, что даже в системах, где информация о пользователе и пароли хранятся на удаленном сервере, getent
все еще может получить информацию о пользователе:
getent passwd
вместо анализа / etc / passwd
getent group
вместо синтаксического анализа / etc / group
Если третий параметр указан выше, отображается только соответствующая запись. (Существуют также shadow
и gshadow
, но getent
предоставляет информацию только пользователям с особыми привилегиями.)
Вывод getent group foo
выглядит примерно так
foo:x:1001:user1,user2,user3
, где первое поле - это имя группы, второе поле - пароль группы ( *
без пароля или x
, если он есть только в файле gshadow
), третье поле - это номер идентификатора группы, а четвертое поле - это разделенный запятыми список пользователей, имеющих эту группу в качестве дополнительной группы. .
Команда cut -d ':' -f 4-
удаляет первые три поля, разделенных двоеточиями, из каждой строки. (Или, другими словами, он выводит только четвертое и любые последующие поля, разделенные двоеточиями, из каждой строки ввода.) Это удаляет имя группы, ссылку на пароль и номер идентификатора группы.
tr -s '\ n,' '\ n \ n'
преобразует все запятые в символы новой строки и объединяет все следующие друг за другом символы новой строки (и запятые) в одну новую строку.
Таким образом, вывод - это просто имена пользователей с foo
в качестве дополнительной группы, по одному имени пользователя в строке.
В список не входят пользователи, основная группа которых ( id -gn
) - foo
; только те, у кого есть foo
в качестве дополнительной группы ( id -Gn
).
Если вы хотите перечислить пользователей, у которых foo
в качестве основной группы, используйте, например,
getent passwd | awk -F ':' '$4=='$(id -g foo)' { print $1 }'
На этот раз мы выгружаем всю базу данных passwd и фильтруем ее с помощью awk
.
Часть $ (id -g foo)
фактически находится вне одинарных кавычек и, таким образом, расширяется до идентификатора группы group foo
.Правило awk сравнивает четвертое поле, разделенное двоеточиями, в каждой строке с номером идентификатора группы (группы foo
), и, если оно совпадает, печатает первое поле (имя этого пользователя).
Команда lastlog
может использоваться для получения регистрационной записи пользователей. Параметр -t
позволяет указать количество дней, учитываемых для записи.
Локализован вывод (в частности, формат даты) команды lastlog
. Это означает, что языковой стандарт пользователя влияет на способ отображения дат в выводе lastlog
. Если вы хотите, чтобы выходные данные всегда были на английском языке и использовали английский формат даты, используйте
LANG=C LC_ALL=C lastlog
LANG = C LC_ALL = C
- две переменные среды, наиболее часто используемые для установки языкового стандарта. Оболочки позволяют временно переопределить среду для одной команды, просто поместив их перед самой командой.
Например, чтобы перечислить только пользователей, которые не входили в систему за последние 10 дней, вы можете использовать
LANG=C LC_ALL=C lastlog -t 10 | awk '/Never logged in/ { print $1 }'
Обратите внимание, что это не ограничивает выбор членами группы foo
, хотя .
Вы всегда можете проверить, членом каких дополнительных групп является пользователь, используя
id -gn username
В Bash вы можете использовать
groups=" $(id -gn "$user") "
if [ "${groups// foo / }" != "$groups" ]; then
# user $user is a member of group foo
else
# user $user is not a member of group foo
fi
, чтобы проверить, является ли пользователь $ user
членом группы foo
. (Опять же, это проверяет только дополнительные группы, а не основную группу. У каждого пользователя есть одна основная группа, и это можно получить с помощью id -Gn "$ user"
.)
Это работает, потому что $ groups
сначала устанавливается в разделенный пробелами список дополнительных групп для пользователя $ user
, с начальным и конечным пробелами. Обратите внимание на цитату! Выражение Bash $ {groups // foo /}
расширяется до значения $ groups
,но все экземпляры foo
(обратите внимание на начальный и конечный пробелы) удалены (заменены пробелом).
Предложение if
сравнивает значение $ groups
с удаленным foo
со значением $ groups
. Если они отличаются, то $ group
должно содержать foo
. Если вам это не нравится, вы можете использовать эквивалент
if id -Gn "$user" | tr -s ' \n' '\n\n' | grep -qxF foo ; then
# user "$user" is a member of group foo
fi
Здесь tr
объединяет все следующие друг за другом пробелы и символы новой строки в новые строки, разделяя имена групп для каждой на отдельной строке. grep -qxF foo
выполняет «тихую» команду grep ( -q
), то есть ничего не выводит, только возвращает успех или неудачу (и в конвейерной команде, подобной той в Bash , успех / неудача определяется последней командой в конвейере); параметры -x
означают, что сравниваются целые строки (поэтому мы не принимаем все группы , содержащие foo
в них, только группы , точно соответствующие foo
); и, наконец, опция -F
означает, что grep
интерпретирует foo
как фиксированную строку, а не как регулярное выражение. (Это имеет значение только в том случае, если foo
должен содержать символы со специальным значением в регулярных выражениях, например *
, [
, ]
и т. Д. on.)
Чтобы написать сценарий Bash, как описано в вопросе, вам понадобится что-то из вышеперечисленного - есть как минимум два разных способа использовать некоторые из вышеперечисленных для решения этой проблемы - плюс некоторый вид "чтения каждый ввод в цикл "переменная", т.е.
some command | while read line ; do
# Here, "$line" iterates through the lines
# output by some command
done