Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am currently exploring Debian packages, and I have been reading some code samples. And on every line in, for example, the postinst script is a pattern.

some command || true
another command || true

So if some command fails, then the line returns true but I don't see how this affects the output of the program.

share|improve this question
3  
Yeah, things that were found out in the discussion belong in the answers, not edited into the question. I suggest that edit be rolled back, as the question makes more sense without it. – IMSoP 2 days ago
    
@StephenKitt I agree, thus I rolled back. – carpenter 22 hours ago
1  
FYI, ||: is another idiomatic way of writing this (: being another entry in the builtin table pointing to true -- but guaranteed to be a builtin even back to Bourne; that said, for POSIX sh, true is likewise guaranteed to be a builtin -- so it's more terseness than efficiency in even-remotely-modern times). – Charles Duffy 15 hours ago
up vote 95 down vote accepted

The reason for this pattern is that maintainer scripts in Debian packages tend to start with set -e, which causes the shell to exit as soon as any command (strictly speaking, pipeline, list or compound command) exits with a non-zero status. This ensures that errors don't accumulate: as soon as something goes wrong, the script aborts.

In cases where a command in the script is allowed to fail, adding || true ensures that the resulting compound command always exits with status zero, so the script doesn't abort. For example, removing a directory shouldn't be a fatal error (preventing a package from being removed); so we'd use

rmdir ... || true

since rmdir doesn't have an option to tell it to ignore errors.

share|improve this answer
    
ah - not knowing debian I did not know of this 'debian installer' convention (-e). Your answer improves on context! And may help me understand why things finish with no error status - while things actually were not error free (and effect stability and/or conflicts with what is documented as 'expected results' when I play 'sandbox' with Debian on Power. – Michael Felt 2 days ago
3  
Well, without set -e there's no need for || true at all, I thought it important to provide the context. If you notice odd things on POWER, I strongly encourage you to file bugs (reportbug)! – Stephen Kitt 2 days ago
9  
@MichaelFelt, actually set -e is not only "Debian convention", but a good programming pattern one should always use. See. e.g. davidpashley.com/articles/writing-robust-shell-scripts – Kay 2 days ago
2  
per the question here - why use || true set -e is the likely context and likely the most common. I bow to this answer! Literally though, it is useful anytime exit status is deemed irrelevant AND (as you article link adds) I am not using exit status as part of my script control. I see utility (in set -e) but would not go so far as the article does and say "Every script you write should include set -e at the top". It is a style of programming. "ALWAYS | Every" includes it own set of traps - aka - absolutes re: wild-card solutions will ALWAYS backfire eventually aka - no free rides. – Michael Felt 2 days ago
1  
@Kay That's a currently popular perspective but is ultimately mired with numerous assumptions which limit the script's portability. There are historical inconsistencies with set -e behavior. It might not matter to you, if your only targets are bash and the other relatively recent shells that live at /bin/sh, but the situation is more nuanced when you want to support old shells/systems. – mtraceur yesterday

While it does not affect the output of the program just run - it permits the caller to proceed as if all is okay aka affects future logic.

Rephrased: it masks the error status of the previous command.

michael@x071:[/usr/sbin]cat /tmp/false.sh
#!/bin/sh
false

michael@x071:[/usr/sbin]cat /tmp/true.sh 
#!/bin/sh
false || true

michael@x071:[/usr/sbin]sh /tmp/false.sh; echo $?
1
michael@x071:[/usr/sbin]sh /tmp/true.sh; echo $? 
0
share|improve this answer
3  
That's true, but it doesn't answer why masking a command's exit status is useful. – moopet 2 days ago
3  
set -e means that the script will instantly terminate upon a non-zero return. You might, in that localized spot, not want that happening! – rackandboneman 2 days ago
    
I am a simple person - and for me the only reason to mask the error status is because it is "in the way". set -e makes any error "in the way" if before you did not care. I like the discussion because I see it as a nice way to help me debug my scripts and write additional logic to respond to an error (e.g., || print -- "xxx existed non-zero here". More likely though I have a shell function 'fatal' and I have "something || fatal "unhappy me". imho a script should report a failed status, or not care. -e plus || true is masking errors. If that is what I want - fine, if not, I am missing errors – Michael Felt 2 days ago
    
what I have to ask myself is: is || true - a coding crutch (lazy way to get around/past an error I do not want to deal with now; a debug tool (-e but no || true) or just someone's dogma about what good coding practice is. In other words - I see it as a feature - with potential benefit. I do not see it as a magic wand to cure all. In short - just as beauty is in the eye of the beholder - set -e and || true utility will be defined by the traits and goals of the programmer. – Michael Felt 2 days ago
5  
@MichaelFelt Consider: git remote remove foo || true git remote add foo http://blah - we want to ignore the error if the remote doesn't exist. – immibis yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.