/systools

Misc. scripts and tools.

Primary LanguageRuby

SysTools

A small collection of random utility scripts. The scripts are written mostly in Ruby. These scripts are quick hacks and should not be considered good code or good practice.

Below are descriptions of some but not all of these scripts along with some potential use-cases.

spath

Usage: spath [path]

Copies the absolute path to the target directory 
to the system clipboard. 
If path is not given, it defaults to current directory.


Prints the absolute path of the file and if possible copies the path to the system clipboard using whichever clipboard copy tool it can find.

Use Case: You have two xterm windows and you would like to quickly share a path between them. You can run spath with no arguments, in which case it will print out the current path and copy it into your clipboard. At this point, you can paste that into another terminal and do whatever you want with it. You can also run spath with an argument, the path to a particular file, and it will do the same thing. If you are on i3wm or tmux, you can comfortably go around copy and pasting paths without taking your hands off the keyboard.

This was a simple bash script, and it was rewritten in Ruby for some reason. It now supports multiple paths.

netfirstport

Usage: netfirstport <port_beg> <port_end>
  Where port_beg <= port_end

Give me the first unused port in the specified port range.

Use Case: You want to run some local server, you prefer some port range, but you're okay with some of those ports being taken. Written in Perl. This parses the output of netstat and gives you the first unused tcp port in the range provided.

pgforcedisconnect

Usage: ./pgforcedisconnect -d <database> [-p <port>]

This script forcefully disconnects all connections
on a particular database.

  -h, --help
    Display this help.
  -d  
    The name of the database.
  -p  
    The Postgres server port.
    Defaults to 5432.


Use Case: You're trying to do something to a Postgres database and it's complaining that there are connections and therefore it won't do what you want it to do. You know that the connections you have are all managed in that they will reconnect as needed. Use this to disconnect all the connections to some Postgres database.

It supports options like port because someone is bound to be running a postgres server on a non-standard port.

pgsqlrestore

Usage: ./pgsqlrestore <dump_path.sql> [--dbhost (dbhost|localhost)] [--dbuser (dbuser|postgres)]
-h, --help:
  Show help
-a, --dbhost:
  Database Host. Defaults to localhost.
-u, --dbuser
  Database User. Defaults to 'postgres'.
-n, --dbname
  Database Name. Defaults to 'restored_[timestamp]'.

This is really ugly and probably wrong, but it does work in most cases.

Use Case: Your friend just handed you a SQL dump from a postgres database, not a binary dump from pg_backup. You need to do some work on this data quickly. You try to restore via psql, but there are active connections that you need to disconnect. Another issue is that the SQL file contains roles that do not exist causing restoration errors. This ugly script will take care of it.

backlight

Usage: backlight <get|set [value]>

-h, --help
  
  Print this help message.


Set or get the backlight value via sysfs.

Use Case: You just installed some minimalistic Linux distribution, you do not have X installed, and your screen is too bright or too dark. Known only to work on my old dell XPS. Use at your own discretion.

cpp_debug_undefined_ref

Typical usage when used with makefile:

$ make 2>&1 | cpp_debug_undefined_ref

This is a simple script, it greps all the undefined references and sticks them into a Set. At the end you get a summary of all the undefined references.

Use Case: You're trying to compile some large project and you do not know all of the dependencies. You either cannot find the documentation or the documentation does not exist. You run make, you see a giant wall of undefined references. Something is missing, but it's hard to see exactly what. You simply pipe the output to this script, and you see that it's mostly OpenSSL functions that are undefined, you link OpenSSL, and now things are working.

sfind

Usage: sfind </some/directory> [options]
        --pruneif CONDITION          Prune if this condition is true
        --pruneunless CONDITION      Prune unless this condition is true
        --prunehidden                Prune Preset. Prune hidden directories
        --matchif CONDITION          Match if this condition is true
        --matchext EXT               Match Preset. Match this extension
        --matchunless CONDITION      Match file unless this condition is true
        --omap MAPPING               Output Map
        --omapxrem PATTERN           Output Map Preset. Grab the first match group
        --osep SEP                   Output seperator
        --oset                       Output is a Set (all items unique)
        --osort [dir]                Output is sorted
        --osortbysize                Sort by Size, Lexographic
        --opal                       Output is palindrome
        --omapxbef BEF               Prepend this string to each output element
        --omapxaft AFT               Append this string to each output element

This started as a build debug tool, but can be used for other things. It's mostly a set of optional evals around Ruby's fantastic 'find' library.

Use Case: Suppose that you want to find all the library files within some directory, that directory has some big sudirectories that you do not want to go into, you want to grab all the library file names, remove the 'lib' part, and output a single space separated line of linker flags all starting with '-l'. This script will let you do all of that with some level of ease.

Example of finding almost all of the boost libraries in some directory:

$ sfind </path/to/boost> --matchunless 'f=~/python|numpy/' --matchext 'a' --omap 'f.basename' --omapxrem 'lib(\w+)\.a' --omapxbef '-l' --osep " "

qcompile

The q here is meant to indicate quick. Written in Perl as a script to run for quickly compiling some tiny demo C or C++ code. Not meant to compile anything serious. It will look at source files and see if any include math.h, if so, it will link against libm. It names the output file after the lead source file.

$ qcompile hello.cpp

Will result in the creation of hello.exe.

ipdefault

Get the ip address of the default interface.

s3backup

Written in Ruby and depends on gem aws-sdk-v1. This one off script was written a long time ago to backup an s3 bucket to some local directory. It skips files that have already been copied, so it should be safe to interrupt and resume.

strace_watch_stdio

This is mostly a wrapper around strace that lets you watch the STDOUT, STDERR, and STDIN of some target process. It takes a PID or a Regex used to find the PID.

Use Case: Suppose some script spawned a process which is misbehaving, you would quickly like to see what it is doing, and you know already that you are logging things to STDOUT. No problem, run this script with the PID or uniquely-identifiable name of the process, and you will hopefully get a sense of what is happening. This is ideal for hard to recreate issues where restarting the process with tee or within tmux is not an option because you would lose whatever conditions caused the process to misbehave.

awaithostport

Usage: awaithostport [<host>:<port>] -- <command>

You may have more than one <host>:<port> before the <command>.

This script will busywait until all <host>:<port> sockets
are reachable before executing the <command>. 

-h, --help

  Print this help string.


Use Case: Suppose you have set of services running in docker-compose or something similar, you want to make sure your database service is up and reachable before your application boots. You can use this script to ensure that one or more host-ports are open before running some command.

Example, you want to wait for Redis on port 6379 to be up on localhost before saying hello:

awaithostport localhost:6379 -- echo hello

ssh-config-parse

Usage: ssh-config-parse [-c /path/to/ssh/conf]

-h, --help
  
  Print this help message.

-c, --config        

  Path to SSH config file.
  Defaults to $HOME/.ssh/config

-m, --mode
  
  Set the mode. Defaults to 'praw'.
  Valid modes are:

    'praw'  -- Print output raw. 
    'pjson' -- Print output as JSON.
  
  A mode is required. 

-t, --tag
  
  ssh-config-parse allows extending the normal config file
  with tags with a '#Tag' field. 

  Example:
  ---
  Host server_nickname
  HostName server_real_hostname
  #Tag <whatever-tag-you-like>
  ---

  You can filter the output with these tag names
  using this -t, --tag flag. 

-f, --field
  
  Output only the selected field. 
  In mode=praw,  
    it will output one line per field. 
  In mode=pjson, 
    it will output the fields as a JSON array. 

-j, --json
  
  Shorthand for mode=pjson, will 
  output in JSON whenever possible.


This script will parse your ssh config file and print out some subset of it. It can take a handy '--json' flag to output in JSON.

Use Case: Suppose you have a number of Hosts in your ~/.ssh/config file. You have attempted to assign nicknames sensibly in some reasonable manner, but you wish you could tag hosts and select them according to these tags. With this script, you can add a virtual '#Tag' attribute within a comment under a Host. When ssh-config-parse parses your config file, it will parse these tags into a Set pertaining to that tag. This allows you to use the '-t' or '--tag' flag to list only those entries matching a given tag.

Example SSH config file:

Host droplet-1
HostName 137.100.100.100
#Tag digoc

Host droplet-2
HostName 137.100.100.101
#Tag digoc

Host somethingelse-1
HostName 137.100.200.1

If you now want only the configs tagged with 'digoc' for your Digital Ocean droplets, you can do:

$ ssh-config-parse -t digoc

Output:

Host droplet-1
HostName 137.100.100.100
#Tag digoc

Host droplet-2
HostName 137.100.100.101
#Tag digoc

And if you only want the Host fields, you can do:

$ ssh-config-parse -t digoc -f Host

Output:

droplet-1
droplet-2