Skip to content

Instantly share code, notes, and snippets.

@socheatsok78
Last active August 20, 2022 15:51
Show Gist options
  • Save socheatsok78/e0c4a5e7b8cebadaa28ee395ec5ae9d7 to your computer and use it in GitHub Desktop.
Save socheatsok78/e0c4a5e7b8cebadaa28ee395ec5ae9d7 to your computer and use it in GitHub Desktop.
Useful shell command or cheatsheet

Bash file descriptors explains

The numbers are file descriptors and only the first three (starting with zero) have a standardized meaning:

0 - stdin
1 - stdout
2 - stderr

So each of these numbers in your command refer to a file descriptor. You can either redirect a file descriptor to a file with > or redirect it to another file descriptor with >&

exec 3>&1
# exec 3>/dev/null

echo >&3 "Hello world"

The variable $$ or $BASHPID contains the PID.

See the [manual][1] for more information, including differences between the two.

TL;DRTFM

  • $$ Expands to the process ID of the shell.
    • In a () subshell, it expands to the process ID of the invoking shell, not the subshell.
  • $BASHPID Expands to the process ID of the current Bash process (new to bash 4).

Added entrypoint hook script to make changes management easier

Credit: https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/docker-entrypoint.sh

set -e

if [ -z "${ENTRYPOINT_QUIET_LOGS:-}" ]; then
    exec 3>&1
else
    exec 3>/dev/null
fi

if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
    echo >&3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"

    echo >&3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
    find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
        case "$f" in
            *.sh)
                if [ -x "$f" ]; then
                    echo >&3 "$0: Launching $f";
                    "$f"
                else
                    # warn on shell scripts without exec bit
                    echo >&3 "$0: Ignoring $f, not executable";
                fi
                ;;
            *) echo >&3 "$0: Ignoring $f";;
        esac
    done

    echo >&3 "$0: Configuration complete; ready for start up"
else
    echo >&3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
fi

Usefull Docker Service templates

See: https://docs.docker.com/engine/reference/commandline/service_create/#create-services-using-templates

environmets:
  DOCKER_SERVICE_ID: "{{.Service.ID}}" # Docker Service ID
  DOCKER_SERVICE_NAME: "{{.Service.Name}}" # Docker Service name
  DOCKER_SERVICE_LABELS: "{{.Service.Labels}}" # Docker Service labels
  DOCKER_NODE_ID: "{{.Node.ID}}" # Docker Node ID
  DOCKER_NODE_HOSTNAME: "{{.Node.Hostname}}" # Docker Node Hostname
  DOCKER_TASK_ID: "{{.Task.ID}}" # Docker Task ID
  DOCKER_TASK_NAME: "{{.Task.Name}}" # Docker Task name
  DOCKER_TASK_SLOT: "{{.Task.Slot}}" # Docker Task slot

Read environment variable from secret file

Example: https://github.com/docker-library/mysql/blob/37cf4047a0544046c9ecce8f2885d4f362a227bc/8.0/docker-entrypoint.sh#L210-L227

Code

# usage: file_env VAR [DEFAULT]
#    ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
#  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
	local var="$1"
	local fileVar="${var}_FILE"
	local def="${2:-}"
	if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
		echo "Both $var and $fileVar are set (but are exclusive)"
		exit 1
	fi
	local val="$def"
	if [ "${!var:-}" ]; then
		val="${!var}"
	elif [ "${!fileVar:-}" ]; then
		val="$(< "${!fileVar}")"
	fi
	export "$var"="$val"
	unset "$fileVar"
}

Usage

# Initialize values that might be stored in a file
file_env 'MYSQL_ROOT_HOST' '%'
file_env 'MYSQL_DATABASE'
file_env 'MYSQL_USER'
file_env 'MYSQL_PASSWORD'
file_env 'MYSQL_ROOT_PASSWORD'
#!/bin/bash
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"

Check to see if this file is being run or sourced from another script

Code

# check to see if this file is being run or sourced from another script
_is_sourced() {
	# https://unix.stackexchange.com/a/215279
	[ "${#FUNCNAME[@]}" -ge 2 ] \
		&& [ "${FUNCNAME[0]}" = '_is_sourced' ] \
		&& [ "${FUNCNAME[1]}" = 'source' ]
}

Usage

# If we are sourced from elsewhere, don't perform any further actions
if ! _is_sourced; then
	_main "$@"
fi

Parse a .env (dotenv) file directly using BASH

Credit: https://gist.github.com/judy2k/7656bfe3b322d669ef75364a46327836

# Pass the env-vars to MYCOMMAND
eval $(egrep -v '^#' .env | xargs) MYCOMMAND
# … or ...
# Export the vars in .env into your shell:
export $(egrep -v '^#' .env | xargs)

# Export the vars in .env into your shell
_parse_env() {
	local env_file=$1
	if [ -f "$env_file" ]; then
		export $(egrep -v '^#' $env_file | xargs)
	fi
}

Alternative

# Export the vars in .env into your shell
_parse_env() {
	local env_file=$1
	if [ -f "$env_file" ]; then
		set -o allexport
		source $env_file
		set +o allexport
	fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment