5

I was wonder with someone can help me:

if [ -z $1 ]; then                                                                                                                                                                                                                                                             
  user=$(whoami)                                                                                                                                                                                                                                                         
else                                                                                                                                                                                                                                                                           
  if [ ! -d "/home/$1" ]; then                                                                                                                                                                                                                                           
    echo "Requested $1 user home directory doesn't exist."                                                                                                                                                                                                         
    exit 1                                                                                                                                                                                                                                                         
  fi                                                                                                                                                                                                                                                                     
  user=$1                                                                                                                                                                                                                                                                
fi 

I was studying some bash commands when I saw two commands: -z and -d. I know what they do (first check for blank variable and the second check for existence directory). My question is how I can find descriptions about these commands (i.g man page -d/-z). They can be only used with if-else statement?

1 Answers1

9

The -d and -z are not commands but options to the test and [ utilities. These utilities are built into bash and documented in the bash manual. These utilities and these flags also happens to be standardized by POSIX, so they are available in any POSIX shell, not just bash.

If you're in an interactive bash session, you may get documentation for the built-in variants of these utilities by typing help test (help [ works too, but its text just refers to the documentation for test).

man test and man [ should work too. These manuals describe the external utilities, probably /bin/test and /bin/[, not the ones you use by default in bash.

So for example,

! test -z "$dir" && test -d "$dir" && printf '%s is a directory' "$dir"

is exactly equivalent to

! [ -z "$dir" ] && [ -d "$dir" ] && printf '%s is a directory' "$dir"

or, if you will,

if ! test -z "$dir" && test -d "$dir"; then
    printf '%s is a directory' "$dir"
fi

and

if ! [ -z "$dir" ] && [ -d "$dir" ]; then
    printf '%s is a directory' "$dir"
fi

(! [ -z "$dir" ] would probably be more commonly written [ ! -z "$dir" ] or [ -n "$dir" ], and I've only used the -z test above because it was mentioned in the question, the -d test on an empty string would fail anyway).

See also:

Kusalananda
  • 333,661
  • Is there a reason the explicitly point to an outdated version of the POSIX standard? – schily Jun 01 '18 at 14:08
  • @schily I had an old bookmark. The 2018 edition is mostly the same as the 2016 edition that I linked to (Wikipedia says it's "technically identical" to the 2016 edition) and the page I linked to is identical in both. I'll start using the 2018 edition from now on though. – Kusalananda Jun 01 '18 at 14:19
  • I know that test did not change since then, but there are a lot of other things that did change since then. Some of them have been changed in order to fix bugs in the standard text. So technically identical may still include differences in the text. – schily Jun 01 '18 at 14:48
  • @schily Is there anything else that you can suggest that would improve this answer? – Kusalananda Jun 01 '18 at 15:19
  • The answer is OK and if you remove the year substring in the POSIX URL, you would always get the latest documents under this URL. – schily Jun 01 '18 at 15:22
  • @schily Stéphane Chazelas asked me to include the specific edition in the URLs as the text that I pointed to otherwise may change (possibly introducing a difference between an answer and what's in the linked document). – Kusalananda Jun 01 '18 at 15:26
  • The only thing that may happen to the standard is that it gets extended (in this case, there will be a related entry under "CHANGE HISTORY") or that we disallow what is no longer available. Yesterday, we did e.g. make the cray hardware illegal for the upcoming issue 8 of the standard as it is based on ones complement integer hardware. As a result of that change, CHAR_MIN is now -128 instead of "-127 or less". – schily Jun 01 '18 at 15:36
  • @schily Thanks! I appreciate the input, and I understand. I will open a Meta question about this nonetheless to see what others think. If not for anything other than make people aware of the issue. – Kusalananda Jun 01 '18 at 15:45
  • @schily I see now that his comment to me about specific edition was regarding referring to specific HTML fragments within pages, in which case he advocated linking to the specific edition, which makes sense. – Kusalananda Jun 01 '18 at 15:50