-2

I'm confused about this conditional:

 if [[ ! -z "$1" ]] 

What is this language?

Here is what I'm familiar with for my terminal and bash_profile:

Bash is the shell, or command language interpreter, for the GNU operating system.

and

Simply put, the shell is a program that takes your commands from the keyboard and gives them to the operating system to perform. In the old days, it was the only user interface available on a Unix computer. Nowadays, we have graphical user interfaces (GUIs) in addition to command line interfaces (CLIs) such as the shell.

On most Linux systems a program called bash (which stands for Bourne Again SHell, an enhanced version of the original Bourne shell program, sh, written by Steve Bourne) acts as the shell program.

function parse_git_branch {
    branch=`git rev-parse --abbrev-ref HEAD 2>/dev/null`
    if [ "HEAD" = "$branch" ]; then
      echo "(no branch)"
    else
      echo "$branch"
    fi
  }

  function prompt_segment {
    # for colours: http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
    # change the 37 to change the foreground
    # change the 45 to change the background
    if [[ ! -z "$1" ]]; then
      echo "\[\033[${2:-37};45m\]${1}\[\033[0m\]"
    fi
  }

  function build_mah_prompt {
    # time
    ps1="$(prompt_segment " \@ ")"

    # cwd
    ps1="${ps1} $(prompt_segment " \w ")"

    # git branch
    git_branch=`parse_git_branch`
    if [[ ! -z "$git_branch" ]]
    then
      ps1="${ps1} $(prompt_segment " $git_branch " 32)"
    fi

    # next line
    ps1="${ps1}\n\$ "

    # set prompt output
    PS1="$ps1"
  }

  PROMPT_COMMAND='build_mah_prompt'
Component 10
  • 10,247
  • 7
  • 47
  • 64
Jwan622
  • 11,015
  • 21
  • 88
  • 181

1 Answers1

2

The language is Bash, a modern shell based on the old Bourne shell and (mostly) compatible with POSIX standards.

test aka [

[[ is a Bash extension of the test command also known as [. The test command is a separate executable but since it’s so useful for shell programming, most (if not all) modern shells implement it as a shell builtin. The following commands show that both versions are available on many systems:

$ type -a test
test is a shell builtin
test is /usr/bin/test

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

For more info, see man test or help test (with Bash).

[[

[[ is implemented as a Bash keyword (not an external command). It originally came from the Korn shell and works similarly but has many improvements over the original [ command. See the following for more info:

Specific example

According to man test (POSIX specification)

−z string True if the length of string string is zero; otherwise, false.

Thus, the [[ -z "$1" ]] construct returns 0 (value for True in Unix shells) if $1, the first positional parameter to a script or function is an empty string. Introducing the negation ! operator converts the expression to its Boolean opposite, i.e, False if the following expression evaluates to True and vice versa.

To sum up, the whole expression evaluates to True if the first argument to the function is a non-empty string and False if it’s empty (or possibly not set at all).

If you read the above links, you’ll notice that [[ ! -z "$1" ]] is actually equivalent to [[ -n "$1" ]] which return True if $1contains anything, i.e., is not empty. This can be further shortened to [[ $1 ]] as quotes aren’t required for variables within [[.

Note: the portable version (for POSIX shells) is [ -n "$1" ] or [ "$1" ] (where the variables have to be quoted to protect from pathname expansion, word splitting and other potential side effects). See http://mywiki.wooledge.org/Quotes for more info.

Functions

The remaining code are shell functions which look like they’re used to build up a colourful prompt which provides details of the status of a git repository if the current working directory is under version control.

Community
  • 1
  • 1
Anthony Geoghegan
  • 11,533
  • 5
  • 49
  • 56
  • This can even be shortened to `[[ $1 ]]` (careful, you have a space missing—and the quotes are unnecessary (though harmless)). – gniourf_gniourf Mar 08 '16 at 09:41
  • Quotes are not here to prevent from variables containing `-n` (for example, `[ -n ]` works as expected: returns `0` (true)—it's a special case of the `test` statement with a single argument); quotes are here to protect from pathname expansion and word splitting. – gniourf_gniourf Mar 08 '16 at 09:52
  • 1
    `[` is an ordinary command (whether or not it is implemented as a built-in), so all the regular rules of expansion apply to its argument(s). `[[ ... ]]`, however, is similar to what is called a special form in Lisp; it has its own rules for how the expression inside is evaluated. In particular, you can treat it as if `[[` itself performs the parameter expansion, letting it interpret the values directly, rather than having the shell expand them and passing the result *to* `[[`. – chepner Mar 08 '16 at 12:53
  • @AnthonyGeoghegan clarify this: 'Accordingly, [[ -z "$1" ]] construct returns 0 (True) if $1, the first positional parameter is an empty string. However, the addition of the ! operator returns the negated value (False instead of True).' – Jwan622 Mar 09 '16 at 06:05
  • 0 is a true value in UNIX shells and -z does some kind of 0 or 1 conversion it seems? – Jwan622 Mar 09 '16 at 15:10
  • @Jwan622 It's the `!` negation operator that converts the value to its opposite. – Anthony Geoghegan Mar 09 '16 at 15:21
  • What does the -z do though? It seems like it converts a value to 0 or 1. "the [[ -z "$1" ]] construct returns 0 (value for True in Unix shells) if $1, the first positional parameter to a script or function is an empty string." So if $1 is the string "hello" which is perhaps truthy in Bash, the -z converts it to 0 which is True in Unix shells right? – Jwan622 Mar 10 '16 at 04:43
  • The documentation for `-z` is quoted in the answer. – Anthony Geoghegan Mar 10 '16 at 09:55