Μηνιαία αρχεία: Απρίλιος 2016


Bash: Determine state of file

Following you will find some tests one can perform on a file to identify its state

Check if file $FILE does not exist

if [ ! -f "$FILE" ]; then
    echo "File $FILE does not exist";
fi

Check if file $FILE exists and is a directory

if [ -d "$FILE" ]; then
    echo "File $FILE exists and is a directory";
fi

Check if file $FILE exists and is a regular file (not a directory)

if [ -f "$FILE" ]; then
    echo "File $FILE exists and is a regular file (not a directory)";
fi

Check if file $FILE exists, we do not know what type it is (if it is a directory, socket, node, etc.)

if [ -e "$FILE" ]; then
    echo "File $FILE exists, we do not know what type it is (if it is a directory, socket, node, etc.)";
fi

Check if file $FILE exists and is a symbolic link

if [ -L "$FILE" ]; then
    echo "File $FILE exists and is a symbolic link";
fi

Check if file $FILE exists and is a socket

if [ -S "$FILE" ]; then
    echo "File $FILE exists and is a socket";
fi

Check if file $FILE exists and is not empty

if [ -s "$FILE" ]; then
    echo "File $FILE exists and is not empty";
fi

Check if file $FILE exists and is readable

if [ -r "$FILE" ]; then
    echo "File $FILE exists and is readable";
fi

Check if file $FILE exists and is writable

if [ -w "$FILE" ]; then
    echo "File $FILE exists and is writable";
fi

Check if file $FILE exists and is executable

if [ -x "$FILE" ]; then
    echo "File $FILE exists and is executable";
fi

Bash: How to iterate over associative array and print all key/value pairs

The values of an associative array are accessed using the following syntax ${ARRAY[@]}.

To access the keys of an associative array in bash you need to use  an exclamation point right before the name of the array: ${!ARRAY[@]}.

To iterate over the key/value pairs you can do something like the following example

# For every key in the associative array..
for KEY in "${!ARRAY[@]}"; do
  # Print the KEY value
  echo "Key: $KEY"
  # Print the VALUE attached to that KEY
  echo "Value: ${ARRAY[$KEY]}"
done

NOTE: The use of quotes around the array of keys ${!ARRAY[@]} in the for statement (plus the use of @ instead of *) is necessary in case any keys include spaces.


Bash: Grep lines that start with a tab character

Using a regular expression to match the lines that start with a tab we wrote the following

grep -P '^\t'

The -P parameter (or –perl-regexp) directs grep to interpret the pattern as a Perl regular expression.

The ^ character directs the pattern to match the start of the line.
The \t character directs the pattern to match a tab character.


Bash: Determinate state of variable

A variable in bash (and any POSIX-compatible shell) will be in one of the three following states:

  • unset
  • set but empty
  • set and not empty

Variables in bash do not have data types. A variable can contain a number, a character, a string of characters or the empty string. Assigning a value to the reference of a variable will create it, you do not need to declare it beforehand.

Following, you will find some tests that allow you to find which state the variable is in. They will allow you to distinguish between ‘unset’ and ‘set but empty’ states.

# Test if VAR is 'unset' or 'set but empty'
if [ -z "${VAR}" ]; then
	echo "VAR is 'unset' or 'set but empty'";
fi

# Test if VAR is 'unset'
if [ -z "${VAR+BFNET}" ]; then
	echo "VAR is 'unset'";
fi
# Where ${VAR+BFNET} is a parameter expansion which evaluates to null if VAR is 'unset',
# if VAR is set to anything (including the empty string) the construct expands to BFNET.

# Test if VAR is 'set but empty'
if [ -z "${VAR-BFNET}" ]; then
	echo "VAR is 'set but empty'";
fi
# Where ${VAR-BFNET} is a parameter expansion which evaluates to the value of VAR if VAR is 'set' (either empty or not),
# if VAR 'unset' the construct expands to BFNET.
# This is useful for providing default values
# For example:
#function custom_echo () {
#    local DEFAULT_MSG="No message passed."; # Doesn't really need to be a local variable.
#    MESSAGE=${1:-$DEFAULT_MSG}; # Defaults to default message.
#    echo -e "$MESSAGE";
#    return;
#}
# In the above function if the user does not provide the message to be printed with the function call, then the default message will be used.

# Test if VAR is 'set and not empty'
if [ -n "${VAR}" ]; then
	echo "VAR is 'set and not empty'";
fi

Following is a truth table for the above:

                        +-------+-------+--------+
                VAR is: | unset | empty | filled |
+-----------------------+-------+-------+--------+
| [ -z "${VAR}" ]       | true  | true  | false  |
| [ -z "${VAR+BFNET}" ] | true  | false | false  |
| [ -z "${VAR-BFNET}" ] | false | true  | false  |
| [ -n "${VAR}" ]       | false | false | true   |
+-----------------------+-------+-------+--------+