4

I'd like to have either a shell script or makefile to automate new user creation. I can't decide which of approach is better - a script or makefile?

I have two types or users - both are SFTP chrooted, individual account and a shared account for web domains.

New users "register" with an email address and I check DNS MX record if the domain is valid and RCPT if username is valid recipient.

Then I cannot use useradd -m as it would create homedir owned by the user, but for SFTP chroot it must be root owned and not writable by anybody else. Thus I create the dir and dir layout manually.

I can't also use userdel -r to remove such user completely, as userdel -r won't remove homedir if it is not owned by the user (at least on OpenBSD).

What's better for such task, a script or a makefile?

PS: I don't want to go with ansible etc...

1
  • I wrote both for now, they do the same. The Makefile is half of length of the ksh script :)
    – Jiri B
    Commented Jan 26, 2019 at 2:22

1 Answer 1

8

I strongly suggest to use a script and not a makefile.

The reasons are, in short:

  • adhering to common practice. or the principle of least astonishment.
  • maintainability and extensibility.
  • and the fact that makefiles are designed to automate a build process, not to automate sysadmin tasks.

It is not inherently "wrong" to use a makefile, it has it's benefits, but also a lot of caveats. Whatever you decide you should know the trade offs.

Let me elaborate.

adhering to common practice or the principle of least astonishment

When I see a script I assume it automates something. When I see a makefile I assume it builds something. When I work in your office and I want to add a user and I look in the documentation and it says to run a makefile I will be confused at first. Will the makefile build the tool that I then use to add a user? I will have to examine the makefile to make sure it really does add a user.

maintainability and extensibility

Change happens. Systems change. Requirements change. Tools will need to be adapted. Here are some caveats I can think of when trying to adapt a makefile that is used to automate a sysadmin task.

In no particular order:

  • You have to prepend every line in the recipe with a tab (see makefile rule syntax defintion). Maybe this is just my personal annoyance. It can be overcome with a good editor which can be configured to not replace the leading tab with spaces in makefiles. workaround possible with .RECIPEPREFIX but then you are again breaking common expectation.

  • You can't (easily) handle arguments in makefiles. This will make it very hard to add arguments like --verbose or --force or --no-action. See here for more explanation: https://stackoverflow.com/a/45003119/360899

  • In addition to above: you can't customize the argument handling error messages. In other words: you can't write meaningful error messages if the user gave incorrect arguments

  • You can't (easily) extract common code to functions. There are "canned recipes". But I'd rather not.

  • You can't (easily) write multiline shell script constructs because make executes every line in the recipe for itself. For example if [ condition ]; then commands; fi or for elements; do commands; done has to be written in one line. workaround possible using .ONESHELL

  • Also, because of the above, you can't (easily) set a flag in one line and act on the flag in a line further down. Because each line stands on its own. workaround as above.

  • Other arcane makefile quirks. For example:

Bonus problem: you can't put a makefile in /usr/bin or ~/bin. you will need to write a wrapper script anyway.

makefiles are designed to automate a build process, not to automate sysadmin tasks

Using makefiles to automate system tasks would be like using git, instead of rsync, for system backup.

Make is a powerful tool with a lot of quirks to automate build processes. Git is a powerful tool with a lot of quirks to do code versioning. The quirks are tolerable if using the tool is helping a lot. But if there are other tools better meant for the task at hand then why work around the quirks from a tool meant to do something else.


Some demonstration:

The benefit of a makefile, that i can think of, would be that you do not need to write boilerplate for argument handling. Compare:

Makefile:

useradd:
    @echo commands that do the things for useradd

userdel:
    @echo commands that do the things for userdel

Script:

#!/bin/sh

if [ $# == 0 ]; then
  echo "need argument: useradd or userdel"
  exit 1
fi

if [ "$1" == "useradd" ]; then
  echo "commands that do the things for useradd"
elif [ "$1" == "userdel" ]; then
  echo "commands that do the things for userdel"
else
  echo "unknown argument: $1"
  exit 1
fi

But then:

$ make userdell
make: *** No rule to make target 'userdell'.  Stop.
$ ./script.sh userdell
unknown argument: userdell

you can't customize the error messages.

$ touch userdel
$ make userdel
make: 'userdel' is up to date.

if a file named userdel exists, for whatever reason, make will correctly deduce that there is nothing that needs to be done.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .