Shell Function to Execute a Command and Return the Output

'Shell', whatever that means is one or other species of a collection of ancient language families complicated by an indefinite permutation of complementary, supplementary, and conflictiary forward, backward, and sideward compatibility relations. Lately shell usually means bash, although I know there will be disputes even here. The primary argument for this convention is that all major distros are setup with bash as the default shell. Being an ancient language, its quirks and compatibility knots are more intrusive than what one would desire coming from experience with modern languages, so any idiom that is well completed, clear, and expressive feels like an achievement worth recording.

Here is a function that I created but, after code review, discovered I did not need, but also want to remember. It executes its first argument and 'returns' its output into its second argument. Whether this is actually 'POSIX compliant' I do not know, but that it works on GNU Bash 4.1+ seems to be careful enough to certify my uncertainty constraints.

function EXECUTE()
{
    # $1: Command to execute
    # $2: Capture the output

    if [ -n "${MY_SCRIPT_TEST}" ] ; then
        LOG "${FMT_BLUE}" '' "Would have executed: ${1}"
    else
        LOG "${FMT_MAGENTA}" '' "Executing: ${1}"
        # Set arg 2 to the output resulting from the execution of arg 1
        eval "$2='$(eval ${1})'"
    fi
}

Here's the function in the context of some other useful functions that altogether does something that could be useful and well-defined.

function USAGE()
{
    printf -- '%s\n' "This is my script that performs some actions"
    printf -- '%s\n' "set MY_SCRIPT_COLORS=1 to get colorized output and"
    printf -- '%s\n' "set MY_SCRIPT_TEST=1 to pretend"
}


function SETUP_LOG()
{
    local LOG_DIR=${1}

    VALIDATE_DIR "${LOG_DIR}" 'logging directory'

    # Global variables ########################################################
    PRINTF_HAS_FMT_B=''
    ###########################################################################
    printf '%b%s' 'str' &> /dev/null
    [ "$?" = "0" ] && PRINTF_HAS_FMT_B='yes'
}


function LOG()
{
    local MESSAGE_COLOR=$1
    local PROCESS_ESCAPES=$2
    local MESSAGE=$3
    local TIME_STAMP=$(date +'%Y-%m-%dT%H:%M:%S')

    # Process escape sequences in message if requested and available
    if [ -n "${PROCESS_ESCAPES}" ] ; then
        if [ -n "${PRINTF_HAS_FMT_B}" ] ; then
            MESSAGE=$(printf '%b%s' "${MESSAGE}")
        fi
    fi

    # Log to stdout
    if [ -n "${MY_SCRIPT_COLORS}" ] ; then
        printf -- '\e[00;%sm%s\e[0m\n' "${MESSAGE_COLOR}" "${MESSAGE}"
    else
        printf -- '%s\n' "${MESSAGE}"
    fi

    # Log to log file
    if [ -f "${LOG_FILE}" ] ; then
        printf -- '[%s] %s\n' "${TIME_STAMP}" "${MESSAGE}" >> "${LOG_FILE}"
    fi
}


function VALIDATE_DIR()
{
    local DIR=$1
    local DESC=$2

    if [ -z "${DIR}" ] ; then
        LOG "${FMT_RED}" '' "Please provide the ${DESC}"
        exit 1
    fi

    mkdir -p "${DIR}"
    if [ ! -d "${DIR}" ] ; then
        LOG "${FMT_RED}" '' "Cannot ensure directory ${DIR}"
        exit 1
    fi
}


function VALIDATE_ARGS()
{
    # Global variables ########################################################
    FMT_BLACK=30
    FMT_RED=31
    FMT_GREEN=32
    FMT_YELLOW=33
    FMT_BLUE=34
    FMT_MAGENTA=35
    FMT_CYAN=36
    FMT_WHITE=37
    FMT_EXTENDED=38
    FMT_DEFAULT=39

    LOG_DIR='/tmp/my_script'
    LOG_FILE="${LOG_DIR}/my_script.log"
    ###########################################################################

    # Display help message
    local HELP=''
    case "${1}" in
        '-h') HELP='yes' ;;
        '--help') HELP='yes' ;;
        'help') HELP='yes' ;;
        *) ;;
    esac
    if [ -n "${HELP}" ] ; then
        USAGE
        exit 0
    fi

    SETUP_LOG "${LOG_DIR}"
    LOG "${FMT_CYAN}" '' "Executing command line: ${0} ${*}"
}


function EXECUTE()
{
    # $1: Command to execute
    # $2: Capture the output

    if [ -n "${MY_SCRIPT_TEST}" ] ; then
        LOG "${FMT_BLUE}" '' "Would have executed: ${1}"
    else
        LOG "${FMT_MAGENTA}" '' "Executing: ${1}"
        # Set arg 2 to the output resulting from the execution of arg 1
        eval "$2='$(eval ${1})'"
    fi
}


function PERFORM_SOME_ACTIONS()
{
    local TMP_FILE_COUNT=''
    EXECUTE 'find /tmp -type f | wc -l' TMP_FILE_COUNT
    LOG "Temporary file count is ${TMP_FILE_COUNT}"
}


VALIDATE_ARGS $@
PERFORM_SOME_ACTIONS

Whose Proxy?

There are many diagrams and word salads presented in cause of explaining forward and reverse (backward? I like linguistic symmetries) proxies. Munificent logic and inholistic reason thus spewed confounded me in my simple desire to know. Fortunately for you, in a dream I had last night I explained it to a dream person thus, and when I had spoken it I knew it was the reductive idea purged of all contrarian confounding encumberment; clairvoyance having carried it forward until now. There is no need to fret about the client or server not know about the presence of the proxy in either case.

In a forward proxy, the server communicates with the proxy as a client. In a reverse proxy, the client communicates with the proxy as a server.

Random Piths

Frameworks vs Libraries (or Systems vs Tools)

Frameworks tend to make your design decisions for you before your project ever exists so you are always going to be constrained to the framework's approach, which invariably yields a selection of the problem space much smaller than the total space advertised by the framework that it is the solution of. These blind spots arise mainly from the designers' ignorance and/or bliss. Also there are always hidden and abstracted layers of auto code that you don't know about and/or don't want to know about.

Libraries tend to be collections of utilities where each is maximized to their most useful and basic utility without diluting the value of each utility below the threshold of convenience, novelty, or beauty. Good libraries don't impose state or evolutionary patterns on your project.

Conclusion: Use a framework for something dreadfully time or resource constrained with the idea to redo it later.

On Selecting, Editing, and Using a Development Pattern or Design

Often trivial design elements, whether used for pedagogical work or because they posit a facile but expressive symmetry, are extrapolated due to affinity for their deceptively elegant ontology into absurd abstrusions that abrade utility in a most vexing and distracting counterpoint. When the prescribed design presides over the dictates of the existential problem or need set, the design eclipses the problem by a scale measured in orders of magnitude.

Conclusion: Don't code to a design when the design malevolently subverts the problem you are trying to solve.

The Proper Method of Maintaining Institutional Knowledge

Ideally, each engineer on a team will actively promote and disseminate their essential institutional knowledge until at least one complete logical copy thereof exists in and can be assembled from the P2P context of the team's total knowledge collective.

Conclusion: Don't hide or allow to be hidden essential knowledge from the team's communication network.

iptables: -p vs --proto vs --protocol

Observe the following three iptables commands:

# iptables -A INPUT -s 10.20.0.0/24 -d 10.10.0.0/24 -i eth0 -m policy -p esp --dir in --pol ipsec --reqid 1 -j ACCEPT
# iptables -A INPUT -s 10.20.0.0/24 -d 10.10.0.0/24 -i eth0 -m policy --proto esp --dir in --pol ipsec --reqid 1 -j ACCEPT
# iptables -A INPUT -s 10.20.0.0/24 -d 10.10.0.0/24 -i eth0 -m policy --protocol esp --dir in --pol ipsec --reqid 1 -j ACCEPT

Whereas --proto is a valid synonym for --protocol (as are -p, --proto[c[o[l]]]), if it, namely the exact token --proto, appears in the rule after -m policy, it will be appropriated by the policy extension of iptables. Indeed, the resulting rules as reported by iptables -vL are:

# iptables -vL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     esp  --  eth0   any     10.20.0.0/24         10.10.0.0/24         policy match dir in pol ipsec reqid 1
    0     0 ACCEPT     all  --  eth0   any     10.20.0.0/24         10.10.0.0/24         policy match dir in pol ipsec reqid 1 proto esp
    0     0 ACCEPT     esp  --  eth0   any     10.20.0.0/24         10.10.0.0/24         policy match dir in pol ipsec reqid 1

This token overloading is an unfortunate design conflict, and such subtlety confounded SaltStack's iptables state module, though not its execution module. It's also really confusing unless you know that --proto can be used in two distinct ways in two distinct places.

So, according to the iptables(8) and iptables-extensions(8) man pages, -p, --proto[c[o[l]]] specify "The protocol of the rule or of the packet to check." and --proto as used by the IPSec policy extension matches the encapsulation protocol. Evidently the encapsulation protocol is different from the protocol used for IPSec traffic. I still have more to learn about this, otherwise I would be more helpful here.

strongSwan VPN Between Two VMs

A Pleasant Discovery

In the course of technological events arising from the labor of one's job, frequently the occasion occurs that one finds oneself either forestalled by uncertainty and variability in setting up an unfamiliar system/tool or confused by the complexity of such system/tool and its unwholesome documentation or both. (The appreciable frequency of this scenario being one of the reasons why filtering on flat task lists for job candidates often proves so foolhardy even as it is defended as the safe choice. Rather, Aristotle I think would advise not to look upon a person's resume, but at what that person will do next.)

Read more…

Conjecture Threshold

Today at his blog, Peter Woit responded to some rebuke or other from the stringeratti cabal on his disrespect for their sacred creed and its inevitable ascendance. He's got a severe commenting policy there and I don't begrudge it. I can imagine someone with his votive alert for bullshit borne out of disgust of general delusion as an ecclesiastical order coopts fundamental physics in a way everyone loves to compare to the celebrated hubris that was shattered 113 years ago--I can imagine someone in his position carefully inscribing himself from the ruling academic class with an appreciable buffer that protects comments as well.

But this is my blog and, waxing bold in my own sovereign licensure, I have neither professional apprehension towards the high court of ivy strangled decorum nor reverence for an ostensible ranking of living minds and I grant myself permanent freedom to post whatever I fancy. The following comment was deemed inappropriate for the curated safe comment space on the blog itself:

If we're now in the business of measuring and comparing the 'intelligence' housed in discrete human instances, I'd say that Woit's smarter than any of those anointed to ascend into the high ivory tower incapable of discerning that the multiverse has no clothes, despite whatever whizbang smoke and mirrors they're able to conjure in its favor.

If this comment seems gratuitously homenim, it's because I err towards frustration with the status quo keepers of the theoretical enterprises in fundamental physics rather than wanting or not to construct Woit paean.

Print all iptables rules

It is unfortunate that iptables does not have a simple builtin option that does this, as I'm too impatient to type out this loop every time I need to see what's really going on. I'm for sure too impatient to type out 5 parallel commands. The -S option does not give the same useful formatting as -L and no option can be combined with -vL to request the rules from all tables. I may just have to add this to my shell init.

for table in filter nat mangle raw security ; do printf "\n===== %s =====\n" $table ; sudo iptables -vL -t $table ; done

Bow Technique

Anecdotally

Many years ago I watched an excellent documentary about violinists in which Itzhak Perlman likened the violinist's bow to an "artist's paintbrush", describing how each requires "a lifetime to master". Likewise, I have personal second hand anecdotes from Pinchas Zukerman saying things like the symphonic orchestra is the greatest of all instruments, and that when someone asks you what you play, you should respond that you "play the bow".

From my 24 years of viola playing, I can substantiate these two metaphorical idioms about the bow with my own vicissitudes of the bow kind.

Read more…

HowTo Get a Site's Certificate Fingerprint

I finally got around to setting up TLS to the IRC servers that I use. It is incredible that this is not default or that there does not even seem to be conventional ports. Freenode suggests 6697, 7000, and 7070, but there is an independent draft standard for 6697.

Read more…

Skew Strings

Skew

Monday of this week I synthesized a combination of two obvious observations into a pair of aphorisms:

When hacking while wearing a black hat, one must string together a sequence of bugs to do one's 'job'.

When doing anything else in life, one's job must be done by stringing together a sequence of bug workarounds.

Read more…