0

My default logrotate script for apache is:

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    postrotate
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
}

I understand the output and error redirection on line 6 but can someone please explain the purpose of || true? And what are the potential consequences of omitting that bit?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 4
    The pipeline `foo || true` always has a zero exit status (success), whether or not `foo` has a zero exit status. Usually, this is used to prevent a command from failing when the `-e` shell option is set, so that a command that you expect may fail does not cause the entire script to fail. As to how this applies to a logrotate script, I'll leave that to someone else to post in a full answer. – chepner Jan 31 '14 at 18:20
  • Thanks chepner, could you please post a link to some documentation on that? – But those new buttons though.. Jan 31 '14 at 18:31
  • The `bash` man page? It's simply a consequence of how `set -e`, `||`, and `true` work. – chepner Jan 31 '14 at 18:36
  • 1
    Yes I understand, but the bash man page is about 14,000 lines long and googling "true" or "||" returns nothing useful. Can you offer a link which specifically address this? – But those new buttons though.. Jan 31 '14 at 19:00
  • The shell is an intricate tool. It is well worth your while to devote some time to reading through the documentation to understand how it works. – chepner Jan 31 '14 at 19:08
  • I don't disagree chepner but since I'm currently interested in learning about a specific aspect of the shell and haven't been able to find to documentation which relates, is it too much to ask for a link? Please? I've been searching for this and still coming up with nothing. – But those new buttons though.. Jan 31 '14 at 20:16
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/46543/discussion-between-billynoah-and-chepner) – But those new buttons though.. Jan 31 '14 at 20:21
  • @billynoah: The relevant section of the bash manual is the section which includes the second occurrence of `||`, so it would be really easy to search for it either in `man bash`, or on some web page. It's true that the manual is long. – rici Jan 31 '14 at 20:31

1 Answers1

3

When the logrotate utility runs postrotate (or prerotate) scripts, it checks the error code returned by the script. In particular, when sharedscripts is specified, the error handling is as follows (quoted from man logrotate, emphasis added):

sharedscripts

Normally, prerotate and postrotate scripts are run for each log which is rotated and the absolute path to the log file is passed as first argument to the script. That means a single script may be run multiple times for log file entries which match multiple files (such as the /var/log/news/* example). If sharedscripts is specified, the scripts are only run once, no matter how many logs match the wildcarded pattern, and whole pattern is passed to them. However, if none of the logs in the pattern require rotating, the scripts will not be run at all. If the scripts exit with error, the remaining actions will not be executed for any logs. This option overrides the nosharedscripts option and implies create option.

|| true prevents http reload command from returning an error condition, which avoids the above.

man bash (in the section "Lists") describes ||:

command1 || command2

command2 is executed if and only if command1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list.

man true explains true in detail, but I think the title suffices: "Do nothing, successfully".

In short, command1 || true first executes command1. If that succeeds, the result is success. Otherwise, it executes true, does nothing successfully, and thus succeeds. So it always executes command1 and always succeeds

rici
  • 234,347
  • 28
  • 237
  • 341
  • Thank you, can you please offer me a link where I can read about the usage of `|| true` in a broader context? I've been reading through bash docs and googling and can't seem to find any relevant discussion or info on this. – But those new buttons though.. Jan 31 '14 at 20:19
  • @billynoah: The bash docs describe `||` (in the section "Lists"), where it explains that in `command1 || command2`, `command2` is only executed if `command1` fails, and the result status of the list is the status of the last command executed. `man true` explains `true` in detail, but I think the title suffices: "Do nothing, successfully". In other words, `command1 || true` executes command1. If that succeeds, the result is success. Otherwise, it executes `true`, does nothing successfully, and thus succeeds. So it always executes command1 and always succeeds. – rici Jan 31 '14 at 20:26
  • That "Lists" section is exactly what I was looking for. I'm used to seeing || in conditional if .. then statements and such, but I wasn't grasping that this is actually a conditional command list. so `/sbin/service httpd reload > /dev/null 2>/dev/null || true` is basically shorthand for `/sbin/service httpd reload > /dev/null 2>/dev/null; if [$? -ne 0]; then true fi` ? – But those new buttons though.. Jan 31 '14 at 22:01