Friday, September 2, 2016

How to Create a Quick Web Server

Have you ever had the need to create a web server to perform a test? Well, here are a few quick options on how to do this.

Got Netcat?

If you have Netcat on the server (which is pretty easy to get), then you can do this.
Example 1: Display the date and the text "It works"
nc -kl 10001 -c 'echo -e "HTTPS/1.1 200 OK\r\n\r\n$(date)\r\n\r\nIt works"'
Example 2: Display an index.html file
nc -kl 10001 -c 'echo -e "HTTPS/1.1 200 OK\r\n\r\n$(cat index.html)"'
Example 3: Using HTTPS
a. First get a set of self-signed certificate and key (either generate or download here -http://www.selfsignedcertificate.com/)
b. Add the certificate to the server and run netcate with the following parameters
nc -l -p 10001 -k --ssl --ssl-cert ca.crt --ssl-key ca.key -c 'echo -e "HTTP/1.1 200 OK\r\n\r\n$(date)\r\n\r\nIt works"'

Python

This is the easiest one, as long as you have Python on that system. Just run the commands below and you are set. If you have an index file on that folder, Python will display, otherwise it will do a directory listing.
$ python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...

Friday, December 18, 2015

Bash Scripting - Best Practices

1 - Readability

1.1 - Indentation

There are 3 commonly used indentation practices for Bash (I prefer the first method, however all 3 are "accepted"):
  • 2 spaces
  • 4 spaces
  • tabs (usually 8 spaces)
All examples will be shown using the first indentation method, however for reference here's a comparison between all 3.
Example:
## 2 spaces
if ...
  command
else ...
  command
fi

## 4 spaces
if ...
    command
else ...
    command
fi

## Tabs
if ...
        command
else ...
        command
fi
Indentation for if conditional statements
if [ test ] ; then
  command
elif [ test ] ; then
  command
else
  command
fi
Indentation for for statements
for a b c in $A ; do
  command
done
Indentation for while and until loops
while [ true ] ; do
  command
done
Indentation for case statements
case $VAR in
  true) command ;;
  false)
    command1
    command2
    ;;
  *)
    if [ test ] ; then
      command
    fi
    ;;
esac
Indentation for functions
_funct_do_var() {
  commands
}

1.2 - Comments

Code Comments

You should always comment your code. This will make it easier for others to understand, as well as for yourself should you need to change the script a few months (or years) later.
Make sure that the comments make sense. Do not try to save on typing as additional comments can save you (or someone else) a lot of time in the future.
Example: Commonly used comments
startTMATE() {
  ## Starts tmate handling
  # Launch tmate in a detached state
  $TMATE_BIN -S $TMT_SOCKET new-session -d

  # Blocks until the SSH connection is established
  $TMATE_BIN -S $TMT_SOCKET wait tmate-ready

  # Prints the SSH connection string
  $TMATE_BIN -S $TMT_SOCKET display -p '#{tmate_ssh}' > $LOG

  # Prints the read-only SSH connection string
  $TMATE_BIN -S $TMT_SOCKET display -p '#{tmate_ssh_ro}' >> $LOG
}
Example: In-line comments
## Sets up package manager aliases based on distro
# Settings for Ubuntu
if [[ "$DISTRO" =~ (Ubuntu|LinuxMint) ]] ; then
  alias aptdate='sudo apt-get update'         # Updates package list
  alias aptgrade='sudo apt-get upgrade'       # Updates all packages
  alias apts='apt-cache search'               # Search for package
  alias aptrm='sudo apt-get remove'           # Removes package

  aptinst() {                                # Install package
    if [ -d "${HOME}/bin/var/log" ] ; then
      LOG=${HOME}/bin/var/log/$(hostname)-package-install.log
    fi

    echo -e "$(date)\t-\tInstalling packages: $*" >> "$LOG"
    sudo apt-get install "$*"
  }
fi

Block Comment

Here Document
You can use a here document (EOF) to "trick" Bash in creating block comments.
Example:
alt text
You can read a bit on my other post here.
Bash Built-in Command
You can also use Bash's bultin :, which does nothing.
Here's the definition from Bash's man page:
: [arguments]
    No effect; the command does nothing beyond expanding arguments and
    performing any specified redirections. A zero exit code is returned.
Example:
: '
 your comments here
'

1.3 - Lines

Breaking Line of Code
When breaking long lines of code with \, indent the new lines.
Example:
[ -f "/etc/cups/cupsd.conf" ] && echo \
  "The CUPS configuration file exists" 
Using Empty Lines
You can use empty lines to keep your code clean, even inside code blocks.
Example:
# Downloads this weeks photos
if [ "$THIS_WEEKS_PHOTOS_URL" ] ; then
  cd ${UNSPLASH_DIR}
  for PHOTO_URL in $THIS_WEEKS_PHOTOS_URL ; do

    # Checks if jpg is in the URL
    if [[ $(echo $PHOTO_URL | grep -qi jpg ; echo $?) -eq 0 ]] ; then
      PHOTO_FILE_NAME=$(echo $PHOTO_URL | awk -F/ '{print $4}')

    # else, let's add it
    else
      PHOTO_FILE_NAME=$(echo $PHOTO_URL | awk -F/ '{print $4}').jpg
    fi

    # Get the photo and save as file name
    wget --progress=bar $PHOTO_URL -O $PHOTO_FILE_NAME
  done
fi

1.4 - Misc

  • Avoid the use of back-ticks ` for command substitution. Use $(...) for better readability

2 - Headers and Sections

2.1 - Script Header

Add descriptive headers to the script outlining it's name, what it does, usage and possibly version.
#!/bin/bash

################################################################################
################################################################################
# Name:          tmate.sh
# Usage:
# Description:   Runs tmate and outputs remote string to file
# Created:       2014-10-31
# Last Modified:
# Copyright 2014, Victor Mendonca - http://wazem.org
# License: Released under the terms of the GNU GPL license
################################################################################
################################################################################

2.2 - Sections

Divide your script into sections.
Put all global script variables in one section
#-------------------------------------------------------------------------------
# Sets variables
#-------------------------------------------------------------------------------
Put all functions in one section
#-------------------------------------------------------------------------------
# Functions
#-------------------------------------------------------------------------------
Put all major work in one section (where functions get called)
#-------------------------------------------------------------------------------
# Starts script
#-------------------------------------------------------------------------------

3 - Variables

3.1 - Naming

  • Give meaningful names to variables
  • When using uppercase, make sure the variable is not already being used
  • Avoid starting variables with _

3.2 - Calling

Double quote variables to prevent globbing or word splitting.

4 - Functions

Try to define your functions at the beginning of the script (see sections).

4.1 - Naming

  • Should start with lower case
  • It's good to start with _
  • Upper and lower case are also good
Example:
_lowerIt () {
  BASH_MAIN_VERSION=$(echo $BASH_VERSION | awk -F. '{print $1}')
  if [[ $BASH_MAIN_VERSION -lt 4 ]] ; then
    echo "Not supported with your version of bash"
    return
  fi

  if [ "$1" ] ; then
    echo ${1,,}
  fi
}

4.2 - Local Variables

Keep your function variables local if they are not being used outside of the function.
Example: This script will output "$2400" only once
_myFunction() {
  local extract
  extract='$2400'
  echo "$extract"
}

_myFunction
echo "$extract"

5- Code Smart

New and Deprecated Features
Get to know your version of Bash and any features it may have.
Example: Old and new arithmetic expansion
# New way for arithmetic expansion
$ echo $((4*25/2))
50

# Old way for arithmetic expansion, which will be deprecated
$ echo $[4*25/2]
50
New features
Bash 4 packs new features (like parameter expansion and output redirects). Get familiar with them as they can save you a lot of time.
Examples: Parameter expansion
$ title="bash best practices"

## Case substitution
$ echo ${title^^}
BASH BEST PRACTICES

## String substitution
$ echo ${title/best/worst}
bash worst practices
Examples: stdout and stderr output redirect
# New
ls 123 &> /dev/null

# Old
ls 123 > /dev/null 2>&1

6 - Software

You can also use software to help with your scripts.

6.1 - Syntax Highlighting

Most of today's editors include syntax highlighting, even VIM. Syntax highlighting will help you catch mistakes like a unclosed bracket or quote.

6.2 - Lint

Some editors, like Sublime Text include plugins for lint software. They can be of great help for you coding.

6.3 - Online Tools

There are also sites that can help checking your script (similar to lint), or a small set of commands.
  • explainshell.com - match command-line arguments to their help text
  • shellcheck.net - automatically detects problems in sh/bash scripts and commands

References

Friday, July 31, 2015

How to Send Pushbullet Notifications from Shell

If you use Pushbullet, you know how great the app is for notification. However you may not know that you can also use Pushbullet's API on your computer to send notifications. This comes pretty handy if you are running a script and wants to get some type of confirmation from it.
For example, I have a Raspberry Pi at home that I use for motion detection with IP cameras (with Motioneye). This server monitors Wifi clients and automatically disables the alerts when I'm home, and re-enables them when I leave. I use Pushbullet to get notifications when this happens.
To start, login to your account on Pushbullet and go to Settings.


You should see your "Access Token" on the bottom right (like the image below). Copy that as we will need it.

Now head to GitHub repo for pushbullet-bash and download the script.
Set your PushBullet API key by creating the file $HOME/.config/pushbullet and adding the linePB_API_KEY= with your "Access Token".
The script has the following options:
Actions:
list - List all devices and contacts in your PushBullet account. (does not require
       additional parameters)
push - Push data to a device or contact. (the device name can simply be
       a unique part of the name that "list" returns)
pushes active - List your 'active' pushes (pushes that haven't been deleted).
delete $iden - Delete a specific push.
delete except $number - Delete all pushes except the last $number.
delete all - Delete all pushes.

To view your registered devices use the list option:







And to send a notification to a device, use the push note option. For example, here's how I would send a notification to my cellphone:
$ pushbullet.sh push "Note 4" note "$HOSTNAME" "Your script is complete"
Success


How to Multiline Comments in Bash

One of the things I always missed in Bash scripting was the lack of multiline comments. Well, not anymore. I found the other day that you can trick Bash by using a here file as multiline comment.



Just make sure you don’t mention MY_COMMENT anywhere else in the code.


Tuesday, December 2, 2014

How to Disable Unity's Global Menu - 14.04

When it comes to disabling Unity's global menu, you have two options:
Disable the global menu for specific apps 

Change the global menu to show in the windows title bar (all apps)


1- Disable the global menu for specific apps

Make sure you have dconf-editor installed. You can install it with:
sudo apt-get install dconf-editor
Open dconf-editor and browse to com.canonical.unity-gtk-module.
Enter the name of each application under the blacklist key. They should be in the following format:
['app1', 'app2', 'app3']

Restart the app and you should see it the new menu's.
2- Change the global menu to show in the windows title bar (all apps)
Go to 'System => Appearance' and click on the 'Behaviour' tab. Select the radio box for 'In the window's title bar'