I don't really understand how the second || clause works. I understand that if the packages are different the rm -r node_modules is executed. I however don't understand how the second || works

cmp package.0.json node_modules/package.1.json || { rm -r node_modules || :; npm install; cp package.json node_modules/; }

The cmdA || cmdB snippet means "Run cmdA and if it fails (exits with an exit code other than 0), run cmdB".

From https://stackoverflow.com/q/3224878/4482039: the colon : in bash is a command that does nothing.

Thus, the rm -r node_modules || :; ... snippet can be interpreted as:

  1. Run rm -r node_modules.
  2. If it fails (because the node_modules file/directory does not exist, or we don't have permissions), do nothing (ignore the error)
  3. Run the rest of the line.

This is a way to ignore errors, because in this case errors are expected. Specifcally for rm, this way is safer than the -f flag because it doesn't force the removal of files rm would usually refuse to delete.

  • However, I do not know why ignoring errors this way is necessary, since cmdA ; cmdB means "Run cmdA, then run cmdB anyway"... – Nathan.Eilisha Shiraini Aug 3 '17 at 8:04
  • 2
    It does make a difference if -e is used e.g. for (the rest of) a script. – dave_thompson_085 Aug 3 '17 at 9:21

|| evaluates the right side only if the left side exit status is nonzero (usually it is when it fails). So, according to that the steps are:

  1. cmp package.0.json node_modules/package.1.json
  2. Only if the previous command fails then do the next steps
  3. Run rm -r node_modules
  4. If the step 3 fails then do nothing (: is like a no-op command)
  5. Run npm install
  6. Run cp package.json node_modules/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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