Videos
1) Your code is not correct, you missed one ] bracket somewhere. Probably after [ -z "$2" block.
2) if statement executes following command(s) and then executes block of code enclosed in then .. fi or then .. else keywords if the return value of the command(s) is true (their exit code is 0)
3) [ is just an alias for the test command (try man test). This command takes several parameters and evaluates them. For example, used with -z "$something" flags would return true (0) if $something is not set or is an empty string. Try it:
if [ -z "$variable" ]; then
echo Variable is not set or is an empty string
fi
4) || statement is an OR. Next command would be executed if the previous one returned false statement. So in the statement
if [ -z "$variable" ] || [ -z "$variable2" ]; then
echo Variable 1 or variable 2 is not set or is an empty string
fi
command [ -z "$variable2" ] would be executed only if variable was empty. The same could be achieved with different syntax:
if [ -z "$variable" -o -z "$variable2" ]; then
echo Variable 1 or variable 2 is not set or is an empty string
fi
which should be faster, because it requires only one instance of the test program to be run. Flag -o means OR, so you could read it as:
If variable is not set/empty OR variable2 is not set/EMPTY...
5) Statement "[ ${3:-} ]" means return true if $3 (the third argument of the script) is set.
6) >&2 is a stream redirection. Every process has two outputs: standard output and error output. These are independent and could be redirected (for example) to be written to two different files. >&2 means "redirect standard output to the same location as standard error".
So to sum up: commands between then .. fi will be executed IF the script is run with $1 empty or $2 empty or $3 NOT empty That means that the script should be run with exactly two parameters. And if not, the echo message will be printed to standard error output.
-z STRING means the length of STRING is zero.
${parameter:-word} If parameter is unset or null, the expansion of word is substituted. In your case $3 is just set with a blank value, if $3 do not have any value.
&2 writes to standard-error. I mean the stdout value of the executed command is sent to stderr,
The line
test -z $LOGNAME || echo Logname is not defined
is an OR list, and can be translated as:
DO echo Logname is not defined IF test -z $LOGNAME FAILS
As you mention in your question, test -z $LOGNAME tests whether $LOGNAME is zero length ... and since it isn't, the test fails. Replacing || with && as follows will give you the behaviour you want:
test -z $LOGNAME && echo Logname is not defined
EDIT: As per William Pursell's comment below, test -n (test for a non-zero-length string) and || might make more conceptual sense, but you need to quote $LOGNAME in this case (and in fact it's a good idea to get into the habit of quoting variables in general):
test -n "$LOGNAME" || echo Logname is not defined
test command looks for mentioned file in current folder, If you want check file from another location provide with full path and don't use -z option or use -s option . You can do as below:
test /usr/bin/logname && echo $LOGNAME || echo Logname is not defined
or
test -s /usr/bin/logname && echo $LOGNAME || echo Logname is not define