💾 Archived View for gmi.si3t.ch › sm4llth1ng › 2021-02-03.gmi captured on 2022-04-28 at 17:30:16. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-01-08)

-=-=-=-=-=-=-

CLI commands

Feb 03rd, 2021

Mostly living in the terminal, I have a bunch of aliases and functions to

ease the use of all the programs I daily use.

  $ alias | wc -l
  67
  $ grep "() {" ~/.bash/functions.d/*.sh | wc -l
  22

The ones I used daily are always in my working memory. But when I need

one that is not used so often, I need to "ag" my definitions files.

The past week I have though of defining a basic vocabulary for my usages

that would be homegeneous for calling programs and scripts.

Here are some shortcuts for accessing the web:

  alias safe='links -socks-proxy localhost:9050'
  alias duck='safe https://duckduckgo.com/lite/'
  alias ffx='firejail firefox  > /dev/null 2>&1 &'
  alias pffx='firejail --private firefox  > /dev/null 2>&1 &'

Some function are quite long for exmaple, to setup a tmux session working

on a particular project with three panes (term, test, edit) ; each one

being in the proper folder and environment plus automatically running all

the tests or launching vim at the root of the project.

The idea is to define a set of commands that are easy to remember, and

stable for all usages (whatever being the underlaying program). Each

command having a default behavior to display available actions when

called without argument.

For example, to browse the web, with a default to text mode:

  Usage: web action [ARG]
      search    open duckduckgo in text mode (tor)
      open      open links with optional URL
      safe      open links with optional URL (tor)
      gui       open firefox in firejail mode
      blank     open firefox in private firejail mode

On the development side I use fabric/invoke (tasks.py) to drive my python

projects and makefiles projects in orther languages. The project command

becomes a single way to interact with these various drivers.

  Usage: project command [ARG]
      list      display all projects managed by command
      workon    switch to given project environment
      test      run given tests for the project (all by default)
      cover     compute code coverage for the project
      run       run the project (program or service)
      deploy    deploy project to given production site

And to interact with production services, the service command accepts

some basic actions.

  Usage: services command [ARG]
      list      display list of all production services
      restart   restart given service
      update    update given service dependencies

A first, draft implementation is fully written in bash. The commands are

defined in similarly structured bash files.

A very simple command is a single bash case with shell expressions:

  # web.sh
  function web () {
    local action safe
    safe='links -socks-proxy localhost:9050'
    action="$1"

    case $action in
      search )
        safe https://duckduckgo.com/lite
        ;;
      open )
        links $2
        ;;
      safe )
        safe $2
        ;;
      gui )
        firejail firefox  > /dev/null 2>&1 &
        ;;
      blank )
        firejail --private firefox  > /dev/null 2>&1 &
        ;;
      * )
        _web_usage
        ;;
    esac
  }

  complete -W "search open safe gui blank" web

  function _web_usage () {
    # echo the command usage
  }

More complex commands are implemented using delegation:

  # service.sh
  function service () {
    local action
    action="$1"

    case $action in
      list )
        _service_list
        ;;
      update )
        _service_update $2
        ;;
      restart )
        _service_restart $2
        ;;
      * )
        _service_usage
        ;;
    esac
  }

  complete -W "list restart update" service

Each action is then implemented in its own function:

  # restart the service using infrastructure API
  _service_restart () {
    local service sid token

    service="$1"
    if [[ -z $service ]]
    then
      echo "Usage: service restart <service>"
      # echo all know services
      for service in "${!serviceS[@]}"; do echo $service; done
      return
    fi

    sid=${serviceS[$service]}
    if [[ -z $sid ]]
    then
      echo "Oops, unknown service $service."
      return
    fi

    token="$(gpg -d $TOKEN)"
    if [[ -z token ]]
    then
      echo "Oops, no token no try."
      return
    fi

    curl -X POST --basic --user "$token:" "$URL/service/$sid/restart/"
  }

Finally, all commands are sourced in my bashrc

  # load all commands
  for f in "$config"/commands.d/*
  do
    source "$f"
  done

That's all folks!