0

I would like to execute the following command ruby do_task.rb && say "done".

The problem is that it say nothing if the command failed. How to fix it so that it would always say something (I don't mind if it say "failed" instead of "done", or just always say "done").

Alex Craft
  • 13,598
  • 11
  • 69
  • 133
  • https://stackoverflow.com/a/30508672/469210 – borrible Jan 10 '20 at 11:30
  • 2
    This sintax `command && echo ok` means - print "ok" if command ended with success. If you wish to print something on fail you should use this `command || echo fail` or both `command && echo ok || echo fail` that'll print "ok" on success or "fail" if something went wrong – Ivan Jan 10 '20 at 11:47

3 Answers3

6

Just replace && with a semicolon ;

ruby do_task.rb;say "done"
Francesco Gasparetto
  • 1,819
  • 16
  • 20
  • 2
    I originally voted this down, but after re-reading the question it is a prefectly acceptable answer "or just always say "done"" – tomgalpin Jan 10 '20 at 11:25
4

Simply :

(ruby do_task.rb && say "done") || (say "fail")

Or as suggested by @LéaGris to avoid spawning subshells,

{ ruby do_task.rb && say "done";}||say "fail"

Or

ruby do_task.rb; say "end"
Corentin Limier
  • 4,946
  • 1
  • 13
  • 24
  • 1
    I'd suggest replacing parenthesis with curly braces to not spawn extraneous sub-processes: `{ ruby do_task.rb && say "success";}||say "fail"`. Note the required space after opening and semicolon before closing curly braces. – Léa Gris Jan 10 '20 at 11:31
  • @LéaGris thanks for this remark, I didn't know that :) – Corentin Limier Jan 10 '20 at 11:32
  • 1
    Also given `&&` (Boolean arithmetic multiplication ×) has priority over `||` (Boolean arithmetic addition +), curly braces or parenthesis are not needed for this specific order, test this: `false && echo "success" || echo "fail"`, and `true && echo "success" || echo "fail"`. – Léa Gris Jan 10 '20 at 11:37
  • 1
    You forgot the space after `{ ` and the semi-colon before the `;}`. – Léa Gris Jan 10 '20 at 12:50
  • Don't use `... && ... || ...`; it is not equivalent to `if ...; then ...; else ...; fi`, which is what you really want. – chepner Jan 10 '20 at 12:59
  • @chepner could you explain the difference ? – Corentin Limier Jan 10 '20 at 13:15
  • `a && b || c` will execute `c` if *either* `a` or `b` fails; `if a; then b; else c; fi` will execute `c` *only* if `a` fails. – chepner Jan 10 '20 at 13:26
2

Another way using a message array (need shell with arrays) indexed with the return code.

message=('success' 'failure')
ruby do_task.rb
say "${message[$?]}"

Also note that if return code of ruby do_task.rb is greater than 1, you will need an array with messages at indexes for each return codes.

To maintain a binary success or failure with the method above:

message=('success' 'failure')
ruby do_task.rb
say "${message[$(($?>0))]}"
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
  • 1
    An alternative would be `say "${message[$((! ! $?))]}"`, which I would consider more concise, since the `! !` idiom is used in many programming languages for a similar purpose. Of course this is a matter of taste. – user1934428 Jan 10 '20 at 13:33