SHUSH(1)

🌸 SHUSH(1) β€” General Commands Manual 🌸

okay bestie, sit down, hydrate, because we're about to talk about shush β€” and she's lowkey a main character in the cron world πŸ’…


✨ NAME ✨

shush β€” run a command and optionally report its output by mail πŸ’Œ


✨ SYNOPSIS ✨

shush [ -h | -V ]

shush [ -c dir ] [ -S | -s facility ] [ -vfmk ] name [ ID ]

shush [ -c dir ] [ -H to ] [ -R to ] [ -T to ] -C name [ stdout [ stderr ] ]

shush [ -i | -u | -r ] [ -c dir ]

✨ DESCRIPTION ✨

so, shush runs a command and then optionally reports its output by mail. it's literally the perfect little wrapper around your cron jobs, no cap. 🫢

by default? shush produces zero output while running, because everything (or, like, anything) gets reported by mail instead. it's giving silent but deadly efficient ✨. however β€” and this is the important part β€” configuration errors and critical errors will get reported on the standard error and (optionally) to syslog. so it's not actually silent, she just doesn't do small talk.

⚠️ okay so interrupting shush has dire consequences, including the likely loss of any output from the command. like, it's that serious. so the following commonly used signals are ignored by shush: SIGHUP, SIGINT, SIGQUIT and SIGTERM. 😭

and if you really insist on killing a running instance of shush β€” rather than killing the running managed command, which is what you probably actually want β€” you can use SIGKILL. and honestly? it shall serve as a reminder of how inappropriate such action typically is. πŸ’€ periodt.


for a command to be run using shush, a configuration file name must exist in the configuration directory ($HOME/.shush by default, cutie πŸŽ€). this file defines how the command should be run and when to send reports by mail. for the deets on all the available configuration parameters, go peek at the CONFIGURATION section below β€” it's right there, don't skip it πŸ™ˆ

two additional configuration files may also exist: name.stdout and name.stderr (by default). these are used to look at the standard output and standard error (respectively) produced by the command. for details on how to use these, see the COMMAND OUTPUT section below. πŸ“¬


when the -C option is specified, shush will only load the configuration, optionally analyze the standard output and standard error from the specified files, and finally produce sample reports if desired. it's the "just checking" era, and we love her for it πŸ’–

this may also be used to produce reports if shush failed to properly terminate when running a command. (the standard output and error from the command are normally found in files located under /tmp.) πŸ”


πŸ—“οΈ the crontab management bit (still DESCRIPTION, bestie)

shush is able to manage crontab(5) entries based on configurations defined by the user. and she can do it in one of two ways, iconic:

  1. if a file named schedule exists in the configuration directory, then it is read for scheduling information. each line should contain a single entry containing three fields separated by whitespace(s). the fields are, in order:
    • the hostname for which the entry applies, or the character * to include all hosts 🌈
    • the configuration name
    • and finally, the scheduling information, in the same format as is used by the schedule parameter (see below)

to specify an ID, use name:ID as the second field. iykyk ✨

  1. if there is no file named schedule, then shush checks the configuration directory for configuration files and adds them to the current user's crontab(5) file as specified by the included schedule parameter (see below).
🚨 heads up: files whose names start with the character # or end with the character ~ are ignored. bye girl πŸ‘‹

✨ OPTIONS ✨

she's got range, and every single one of these matters, so buckle up πŸŽ€

  • -h β€” display a brief help message. the "hey bestie what do i do" button 🫢
  • -V β€” display the version information. prefix with -v to display compile time defaults. πŸ‘‘
  • -c dir β€” specify the directory where configurations are stored. πŸ“
  • -s facility β€” defines the syslog facility to use for logging. πŸ“
  • -S β€” disable syslog logging. not today, syslog πŸ’…
  • -v β€” copy information log messages to the standard output. she's chatty now, and honestly? obsessed ✨
  • -f β€” fast mode: any configured randomdelay is ignored. zoom zoom πŸ¦‹
  • -m β€” monitor and display the command's standard output and error in real time. live feed, no delay, main character energy πŸ‘‘
  • -k β€” keep the command's output log files instead of deleting them upon completion. she's sentimental, let her keep the receipts πŸ’–
  • -C β€” check the configuration without running any command. just vibes, no execution πŸ”
  • -H to β€” send a sample HTML report to the specified recipient(s). cute AND formatted πŸ’Œ
  • -R to β€” send a sample enriched report to the specified recipient(s). enriched, as a treat 🌸
  • -T to β€” send a sample text report to the specified recipient(s). plain text, still slay ✨
  • -i β€” use crontab(1) to install a new crontab(5) file for the current user.
⚠️ the user must not already have a crontab(5) file. fresh start only, no exceptions πŸ™ˆ
  • -u β€” use crontab(1) to update the current user's crontab(5) file, which must already exist. glow-up era πŸ’…
  • -r β€” remove any entry added by the -u option from the current user's crontab(5). we're decluttering, bestie 🧹

okay that's part 1 and there's more coming, so don't go anywhere πŸ’œ

πŸŽ€ CONFIGURATION πŸŽ€

okay bestie, so a shush config file is made of a main section, report section(s), and parameters. The main section is the boss β€” it sets the global parameters AND the defaults that reports inherit. Every report section kicks off with the report's name wrapped in brackets. Any line starting with #? Ignored, don't even worry about it πŸ’….

And listen: each parameter should only be written once. Write it more than once and everything except the last one gets ignored β€” unless the page says otherwise, so watch out πŸ™ˆ.

Parameters get written like this:

name=value

or:

name@hostname=value

or:

name%ID=value

or finally:

name@hostname%ID=value

Here's the tea β˜•: the second and fourth formats? They get ignored unless shush is actually running on that hostname. The third and fourth formats let you define multiple instances of one single config file β€” those config files need an instance ID to run at all. And any config line using the third or fourth format gets ignored if the ID on that line doesn't match the instance ID you ran shush with. fr fr, that's the whole vibe.


πŸ’– Parameters that live in the main section πŸ’–

  • command β€” the actual command to run. Before it runs, shush sets two environment variables for it: SHUSH_NAME gets set to name, and SHUSH_ID gets set to ID. slay.
  • config β€” defaults to the full path of the main configuration file. The other two config file names? You get them by appending the .stdout and .stderr suffixes onto whatever this parameter is set to. easy.
  • lock β€” if you set this, it tells shush to grab a lock file before running the command, and it defines what to do when some other process is holding that lockfile. Format is a comma separated list of actions. The valid actions are: a time duration (during which shush just waits and keeps trying to get the lockfile), the string "abort" (meaning shush terminates immediately if the lockfile already exists), the string "ignore" (meaning shush pretends an existing lockfile isn't there), the string "loop" (which marks where to start again from once all the actions have run), and the string "notify=" followed by mail addresses where a notification mail should go. Actions run in the order you give them, and once they're all done, shush will wait forever trying to grab that lockfile β€” unless "loop" is one of the defined actions. Time durations use units of w(eeks), d(ays), h(ours), m(inutes) or s(econds). No unit? It assumes minutes, periodt.
  • lockfile β€” by default, shush uses a file sitting in the same directory as the config file, named after the configuration and host names. Want a different name? This parameter's your girl.
  • lockmsg β€” if you set this, the string becomes the subject line for the lock notification mail message(s). The default is "[%u@%h] **PENDING** %N [%t]". Peep the MAIL SUBJECT section for the format deets πŸ‘‘
  • path β€” shush does not touch the environment, except to set the PATH variable if this parameter is set. that's it, that's the whole thing.
  • randomdelay β€” set this and shush waits up to the specified amount of time before starting the command, unless it was invoked with the -f. Valid time units: s(econds), m(inutes), h(ours), d(ays), w(eeks). No unit specified? It assumes minutes.
  • schedule β€” this defines when to run the command as a cron job, in a crontab(5) compatible format. You can specify multiple entries using the ";" character as a separator, and entries prefixed with the "#" character get skipped. Heads up: shush doesn't actually use this parameter to run the command itself β€” it's used by the -i and -u options. iykyk.
  • sendmail β€” use this to override the command used to send mail.
  • shell β€” by default, the Bourne shell sh(1) runs the command, which means you get to use any shell syntax you want. Define an alternate shell with this parameter if that's your vibe.
  • statedir β€” this defines the directory where shush saves its status, and it defaults to the .state directory under wherever the config lives. If that directory doesn't exist you get an error β€” unless this option wasn't set. Setting this option to an empty string stops shush from saving its status at all. And shlast(1) uses these state files to report on running instances of shush plus previous runs 🫢
  • syslog β€” this one is only used by the -i and -u options, no other effect on shush whatsoever. It lets you override the default syslog facility used for logging (the one defined at compile time). Leave it blank and you suppress the use of syslog entirely.
  • timeout β€” this parameter lets you control how long the command is allowed to run. Should be a comma separated list of actions. Valid actions are: a time duration (during which shush just waits for the command to terminate), a signal (either "SIGNAME" or "-SIGNUMBER") that gets sent to the command's process group, a signal (either "=SIGNAME" or "=SIGNUMBER") that gets sent to the shell used to spawn the command, the string "loop" (marks where to start again from once all the actions have run), and the string "notify=" followed by mail addresses where a notification mail should be sent. Actions execute in the order you give them, and if the command is still running once they're all done, shush waits forever β€” unless "loop" is one of the defined actions. Time durations use units of w(eeks), d(ays), h(ours), m(inutes) or s(econds). No unit? Minutes, assumed, always πŸ’€
  • timeoutmsg β€” set this and the string becomes the subject for the timeout notification mail message(s). Default is "[%u@%h] **TIMEOUT** %N [%t]". Again, MAIL SUBJECT section has the format tea.

🌸 Parameters that can live ANYWHERE in the config 🌸

If you put these in the main section, they become the default settings that apply to any report that hasn't defined that same parameter itself. cute.

  • to, cc, bcc β€” where to send the mail report. yes, all three, one bullet, that's just how they're listed bestie.
  • subject β€” subject of the mail report. MAIL SUBJECT section for the format details.
  • header β€” additional mail header(s). Quick note: you can repeat this parameter to specify multiple headers. But β€” and this is important β€” for any given report, only the headers from the report (if specified) or from the main section will be used. pick a lane ✨
  • hostprefix β€” by default, subjects get prefixed with the host name between brackets. This parameter lets you customize that prefix. A positive integer says how many components of the fully qualified hostname to show. A negative integer says how many trailing components of the fully qualified hostname to trim off. The integer zero means omit the prefix entirely. Oh, and this parameter gets ignored if the "subject" contains any % character. noted.
  • userprefix β€” by default, subjects get prefixed with the username between brackets. This parameter lets you disable that. Any non zero value means show the username, while zero means omit the prefix. Same deal as above: ignored if the "subject" contains any % character.
  • output (previously "stderr") β€” this defines how the command's standard output and standard error get captured and reported back to you: "errfirst", "mixed", "outfirst". When you use "mixed", the name.stderr configuration file is ignored. When you use "errfirst" or "outfirst", individual reports can use one of two extra options: "outonly" and "erronly".
  • format β€” mail messages sending the command's output can go out in three different formats: "text" (the default), "enriched" text, or "html".
  • sizelimit β€” by default the entire output of the command gets sent in mail reports. This parameter limits the size of the output included in a report. Watch out: the total size of mail sent will be greater than this, because the limit has zero effect on mail headers. Size units are m, k, b, c (MB, KB, Bytes). No unit specified? Assumed to be KB. A limit of zero means don't truncate the output at all.
  • if β€” a report only gets sent if no if condition is specified, or if the specified if condition is true. The condition syntax allows the usual logical operators ("||", "&&", "!"), comparison operators ("==", "!=", "<", "<=", ">", ">=") and basic arithmetic operators ("+", "-"). Aside from counters defined by the configuration (scroll to the COMMAND OUTPUT section below πŸ‘€), you can use these variables:
    • $exit β€” if the command terminated normally, this is its exit code. Otherwise it's negative and indicates the signal number that caused the command to terminate (e.g. -1 means signal number 1 caused the command to terminate).
    • $size β€” output size (in bytes), same as "$outsize + $errsize".
    • $outsize β€” size (in bytes) of standard output.
    • $errsize β€” size (in bytes) of standard error.
    • $lines β€” number of lines output.
    • $outlines β€” number of standard output lines.
    • $errlines β€” number of standard error lines.
    • $runtime β€” command run time (in seconds).
    • $utime β€” user time used by the command.
    • $stime β€” system time used by the command.
    • $tty β€” 1 if shush is run from a terminal (like, interactively), 0 otherwise.

that's part 2 babes, keep scrolling, we are NOT done πŸ’œ

πŸ’Œ MAIL SUBJECTS πŸ’Œ

okay so the lockmsg, timeoutmsg and subject parameters can have these lil tokens in them, and they get expanded like this, bestie:

  • %% β€” it's literally just the % character, iconic
  • %h β€” the hostname, slay
  • %<digit> or %-<digit> β€” a partial hostname 🫢 a positive digit tells you how many components of the fully qualified hostname to keep, and a negative digit tells you how many trailing components of the fully qualified hostname to trim
  • %i β€” the instance ID
  • %n β€” the configuration name
  • %N β€” the configuration name and the instance ID, together, as a duo ✨
  • %r β€” the report name
  • %t β€” the elapsed time
  • %u β€” the username
  • %U β€” the userid
⚠️ and listen β€” if the % character shows up in the subject parameter, then the hostprefix and userprefix parameters get ignored. like, fully ghosted. no cap.

πŸ” COMMAND OUTPUT πŸ”

so after your command finishes doing its thing, shush is gonna peek at the contents of the name.stdout and name.stderr files β€” but only if they exist, obvi β€” to look at the output your command produced.

these files are giving simple format energy. every line is one single character (the counter name) followed by a regular expression. that's it, that's the whole vibe πŸ’…

all counters start out initialized to 0 (zero, bestie). then every line of output gets matched against these regular expressions until a match is found. the moment one matches, the associated counter gets bumped up by one. 🌸

and then?? those counters can be used as part of the main configuration, inside an if configuration parameter β€” so the decision to send a mail report can be based on how many times certain regular expressions got matched. it's giving data-driven decisions, we love to see it.

finally, regular expressions can define sub-expressions, and those get rendered in bold in mail reports. main character formatting energy fr fr.

lines starting with the character # are considered comments and get ignored, periodt. and by default, standard regular expressions are used β€” unless the first line is #pcre, in which case Perl compatible regular expressions are used instead. plot twist πŸ¦‹


🌈 ENVIRONMENT VARIABLES 🌈

  • HOME β€” if the -c option isn't used, shush will look for configuration files in $HOME/.shush. so cozy.
  • SHUSH_SENDMAIL β€” if defined, this should point to the sendmail(1) binary. this variable overrides the sendmail configuration setting and should be used with care, bestie. handle with caution, it's giving sharp edges. ⚠️
  • TMPDIR β€” the directory where temporary files are created. πŸŽ€

🧚 EXAMPLE 🧚

the following configuration runs shush -c /etc/shush -u daily at 9:00, updating the user (root) crontab:

command=shush -c /etc/shush -u
schedule=0 9 * * *
lock=notify=root root-logs,abort
timeout=5m,loop,notify=root root-logs,15m
stderr=first
format=text
Subject=Crontab Daily Update
[logs]
to=root-logs
[readers]
if=$exit != 0 || $outlines != 1 || $errsize > 0 || U
to=root
format=rich

the associated configuration for standard output is:

Oshush: crontab updated\.$
U^.+$

and for standard error:

U^(.+)$

okay so here's what's actually going down πŸ’œ a lock will be set while running the command, and mail gets sent to root and root-logs if the lock is held by another process when shush starts β€” in which case shush will abort. a mail will also be sent to root and root-logs if shush -c /etc/shush -u runs for more than 5 minutes, and for every 15 minutes following that first 5 minutes. consistent queen behavior.

upon completion, the output will always be sent to root-logs. additionally, the output will be sent to root if the condition $exit != 0 || $outlines != 1 || $errsize > 0 || U is true. for this condition to be true, one of the following must be true:

  1. the exit code is non zero
  2. the command standard output was not a single line
  3. there was output on standard error
  4. the counter U is non zero

for the counter U to be non zero, there must be output on standard output other than the line shush: crontab updated.. and finally, any line of output produced on the standard error will be displayed in bold in mails sent to root. bold for the drama, honestly obsessed. πŸ”₯


πŸ‘€ SEE ALSO πŸ‘€

crontab(1), pcre(3), regex(3), sendmail(1), sh(1).


⭐ AVAILABILITY ⭐

the latest official release of shush is available on the web. the home page is http://web.taranis.org/shush/ β€” go check it out, iykyk. 🫢


πŸ‘‘ AUTHOR πŸ‘‘

Christophe Kalt <kalt@taranis.org>


πŸ’€ BUGS πŸ’€

the -C option does not allow specifying an ID. πŸ™ˆ

for other bugs, send reports to shush-bugs@taranis.org.


and that's a wrap on the whole page, bestie!! this lil slice of documentation was dated 2007-09-30 23:38:23 and it's the SHUSH(1) manual page β€” a genuine classic, aging like fine wine. go forth and schedule responsibly πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from