0

I'm very simply wondering if, in a bash script, a new line is functionally 100% equivalent to &&?

e.g.:

#!/bin/bash

7z x "${file}"

mv "${file}" "${new_file}"

vs

#!/bin/bash

7z x "${file}" && mv "${file}" "${new_file}"

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

s.k
  • 461

1 Answers1

3

No: && only runs the command following it if the command preceding it succeeds. Thus

7z x "${file}" && mv "${file}" "${new_file}"

only renames the file if 7z completes successfully, whereas

7z x "${file}"
mv "${file}" "${new_file}"

will run mv in all cases (and fail if ${file} doesn’t exist).

See What are the shell's control and redirection operators? for details (in particular, it describes how new lines are also not quite the same as ;).

Stephen Kitt
  • 434,908
  • 1
    Since$file is a parameter that should be 7z x -- "$file" and mv -- "$file" "$new_file" (NB some people seem to think that ${var} is equivalent to "$var") – Chris Davies Mar 09 '24 at 19:35
  • what if we add set -e at the beginning of the second example? Would it then behave the same as the first snippet? – Meto Mar 09 '24 at 21:42
  • Isn't that a good practice to put curly braces around vars? https://nickjanetakis.com/blog/why-you-should-put-braces-around-your-variables-when-shell-scripting – s.k Mar 09 '24 at 22:33
  • @s.k Do both. Writing $A as "$A" prevents shell expanding A into multiple words. Writing $A_B as ${A}_B prevents shell trying to expand an unknown variable A_B instead of expanding A and appending _B. Many of the extended expansions (array, substring, trimming) require the {..} to control the internal syntax. – Paul_Pedant Mar 10 '24 at 10:11
  • 1
    @Meto not quite — 7z … && mv … will only run mv if 7z succeeds, but will continue running after mv if 7z fails; whereas set -e; 7z …; mv … will exit if any command fails, including mv, and anything following mv won’t run if 7z or mv fails. – Stephen Kitt Mar 10 '24 at 12:46