Archive for the ‘ Scripting ’ Category

Ansible – enable logging

Ansible – Enable logging

By default, Ansible logs the output of playbooks to the standard output only. In order to enable logging to a file for later review or auditing, it can be turned on by setting log_path to a path location where Ansible has a write access.

In my case, i have added the “log_path” setting in the ansible configuration file “/etc/ansible/ansible.cfg”

# grep log_path /etc/ansible/ansible.cfg
log_path = /var/log/ansible.log

Now I can view the log file to all the details on ansible runs –

root@linubuvma:/etc/ansible# ansible-playbook tasks/groupby.yml --check
PLAY [all:!swarm:!docker1] ****************************************************

TASK: [group_by key=os_{{ ansible_os_family }}] *******************************
changed: [ns2]

root@linubuvma:/etc/ansible# ls -al /var/log/ansible.log
-rw-r--r-- 1 root root 4255 May 16 21:21 /var/log/ansible.log
root@linubuvma:/etc/ansible# head  /var/log/ansible.log
2015-05-16 21:21:43,732 p=22946 u=root |
2015-05-16 21:21:43,732 p=22946 u=root |  /usr/local/bin/ansible-playbook tasks/groupby.yml --check
2015-05-16 21:21:43,732 p=22946 u=root |
2015-05-16 21:21:43,734 p=22946 u=root |  ERROR: the playbook: tasks/groupby.yml could not be found
2015-05-16 21:21:48,575 p=22954 u=root |
2015-05-16 21:21:48,576 p=22954 u=root |  /usr/local/bin/ansible-playbook tasks/groupby.yml --check
2015-05-16 21:21:48,576 p=22954 u=root |
2015-05-16 21:21:48,594 p=22954 u=root |  PLAY [all:!swarm:!docker1] ****************************************************
2015-05-16 21:21:48,609 p=22954 u=root |  TASK: [group_by key=os_{{ ansible_os_family }}] *******************************
2015-05-16 21:21:48,641 p=22954 u=root |  changed: [ns2]

It logs dry-runs (–check) as well and it is smart enough not to log Password arguments.

References –

ipython – quick introduction

ipython tutorial and how to delete sensitive data from history

ipython is program which allows you to run python code in an interactive shell. Although Python itself when run from CLI opens an interactive shell as well, ipython is much more powerful and greatly improves your productivity. Some of the things you can do with ipython but not the default python shell is command or code and file name completion, view history, copy/paste a single or multiline code, nicely colored help with in the shell, run Linux commands such as ls or cat, scroll up/down to previous commands, automatically adds spaces after you press enter, etc.


pip install ipython

Quick demo
Start ipython by typing the


command in your CLI –

daniel@lindell:/tmp$ ipython
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
Type "copyright", "credits" or "license" for more information.

IPython 5.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: print('ipython')

In [2]: 

With in the ipython interactive shell you can run any python code, let us walk through some examples –

  In [1]: x=2

In [2]: x
Out[2]: 2

In [3]: mylist=[1,2,3,4,5]

In [4]: [i**3 for i in mylist]
Out[4]: [1, 8, 27, 64, 125]

In [5]: with open('/etc/hosts') as fp:
   ...:     for line in fp:
   ...:         if 'localhost' in line:
   ...:             print line
   ...:    	localhost

::1     ip6-localhost ip6-loopback

In [6]: ls /opt/
ansible/  google/  vagrant/

In [7]: 

Go back to previously typed commands / History
With ipython, you can either press the UP arrow key or type


command to view history. ipython keeps session history as well as all input and output lines in a SQLite file which is located in


You can view and modify this file using


tool –

daniel@lindell:/tmp$ sqlite3 ~/.ipython/profile_default/history.sqlite
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE sessions (session integer
                        primary key autoincrement, start timestamp,
                        end timestamp, num_cmds integer, remark text);
                (session integer, line integer, source text, source_raw text,
                PRIMARY KEY (session, line));
CREATE TABLE output_history
                        (session integer, line integer, output text,
                        PRIMARY KEY (session, line));

Deleting sensitive data from history
You can delete any line from history by using SQL. First use SELECT statement to find the line number and then use DELETE statement to delete it. In this example, we are deleting line number 10 from the history table –

sqlite> select * from history;
sqlite> .schema history
                (session integer, line integer, source text, source_raw text,
                PRIMARY KEY (session, line));
sqlite> delete from history where line=10;

References –

How to copy to a clipboard in Linux

Problem statement – You have a file with hundreds or thousands of lines and you want to copy the contents of this file and paste it to an external application, for instance to a browser.

Solution – The first attempt is to try to cat the file and scroll down with your mouse to select each line. This is time consuming or in some cases might not work if there are too many lines as some of the lines will ‘scroll out of the terminal’. One way of getting around this is to use “xclip” – a command line interface to X selections (clipboard).

In my case I wanted to copy the contents of ‘/tmp/ipaddresses.txt’ file to a browser for blogging. The file had 10000 lines. I used the following commands, first to install xclip and then to copy the file contents to a clipboard –

apt-get -y install xclip
xclip -sel cli < /tmp/ipaddresses.txt

The xclip command basically does a selection (-sel) from the file into the clipboard(-cli), where you can copy paste to any other external application.


Cloud service providers IP ranges for Amazon Web Services(AWS), Microsoft Azure and Google Cloud Platform(GCP).

Cloud service provides publish the subnet IP ranges through multiple ways. This information is particularly important if you want to setup firewall rules or proxy whitelisting based on IP address range.

1. Amazon Web Services(AWS)

Amazon publishes its current IP address range in JSON format. You can find it here.

This quick and dirty python script dumps the IPv4 address range –

#!/usr/bin/env python

import sys
import requests

    r = requests.get('')
except Exception as e:
    print('Error making https request : {}'.format(e))

if r.status_code == 200:
    for item in r.json().get('prefixes'):

Run script –

$ python  | tee /tmp/aws_ip_range.txt

2. Google Cloud Platform(GCP)

Google makes its cloud IP address range publicly available in DNS as TXT record. The information on how to query DNS to get the IP address range is here.

For GCP, this quick and dirty shell script can pull the IP ranges –


# array to hold list of IP blocks
txt_records=$(dig @${NAME_SERVER} txt +short)
txt_rr_only=$(echo $txt_records | grep -oP 'include:\S+' | sed 's/include://g')
[[ -z ${txt_rr_only} ]] && { echo 'No TXT dns record found.'; exit 1;}
## unpack txt records to get IPv4 ranges
for rr in ${txt_rr_only}; do
  new_ips=$(dig @${NAME_SERVER} $rr txt +short | grep -o -P '(\d+\.){3}\d+/\d+')
  for item in ${new_ips}; do
    # add space separator between ip blocks
    item=" ${item} "

# sort IPs
echo ${ALL_IPS[@]} | sed 's/ /\n/g' | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4

Run script –

$ ./ | tee gcp_ip_range.txt

3. Microsoft Azure

Microsoft publishes its IP address range in xml format, you can download it from here.

This quick and dirty Python script pulls the IP ranges using BeautifulSoup. Note – this IP range was downloaded on 05/23/2017 – change the date to get the latest data.

#!/usr/bin/env python

import sys
import requests
from bs4 import BeautifulSoup

    r = requests.get('')
except Exception as e:
    print('Error making https request : {}'.format(e))

if r.status_code == 200:
    xml_data = BeautifulSoup(r.text, "lxml")
    ip_range = xml_data.find_all('iprange')
    for ip in ip_range:

Run script –

$ python | tee azure_ip_range.txt

curl – get only numeric HTTP response code

Most browsers have developer plugins where you can see the HTTP status code response and other request/response headers. For automation purposes though, you are most likely to use tools such as curl, httpie or python requests modules. In this post, we will see how to use curl for parsing HTTP response to get only the response code.

1. First attempt – use ‘-I’ option to fetch HTTP-header only.

The first line will show the response code.

daniel@linubuvma:~$ curl -I
HTTP/1.1 200 OK
Date: Sun, 09 Apr 2017 06:45:00 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN; Htty
Transfer-Encoding: chunked
Accept-Ranges: none
Vary: Accept-Encoding

But does this work all the time? No, some web services have problem with the HEAD HTTP request. Let us try for instance –

daniel@linubuvma:~$ curl -I
HTTP/1.1 503 Service Unavailable
Content-Type: text/html
Content-Length: 6450
Connection: keep-alive
Server: Server
Date: Sun, 09 Apr 2017 06:50:02 GMT
Set-Cookie: skin=noskin; path=/;
Vary: Content-Type,Host,Cookie,Accept-Encoding,User-Agent
X-Cache: Error from cloudfront
Via: 1.1 (CloudFront)

daniel@linubuvma:~$ curl -I -A "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20101026 Firefox/3.6.12"
HTTP/1.1 405 MethodNotAllowed
Content-Type: text/html; charset=ISO-8859-1
Connection: keep-alive
Server: Server
Date: Sun, 09 Apr 2017 06:49:47 GMT
Set-Cookie: skin=noskin; path=/;
Strict-Transport-Security: max-age=47474747; includeSubDomains; preload
x-amz-id-1: N2RDV79SBB791BTYG2K8
allow: POST, GET
Vary: Accept-Encoding,User-Agent
X-Frame-Options: SAMEORIGIN
X-Cache: Error from cloudfront
Via: 1.1 (CloudFront)

In the first attempt, was actually blocking automated checks by looking at the user-agent in the header, so i had to trick it by changing the user-agent header. The response code was 503. Once I changed the user-agent, I am getting 405 – the web server does not like our HEAD HTTP (‘-I’) option.

2. Second attempt – use ‘-w’ option to write-out specific parameter.

curl has ‘-w’ option for defining specific parameter to write out to the screen or stdout. Some of the variables are content_type, size_header, http_code. In our case, we are interested in http_code, which will dump the numerical response code from the last HTTP transfer. Let us try it –

daniel@linubuvma:~$ curl -I -s -w "%{http_code}\n" -o /dev/null

We use ‘-I’ to get only the header and redirect the header to /dev/null and only print http_code to stdout. This is by far the most efficient way of doing it, as we are not transferring the whole page. If the ‘-I’ option does not work though, for sites such as, we can drop ‘-I’ as follows –

daniel@linubuvma:~$ curl -s -w "%{http_code}\n" -o /dev/null -A "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20101026 Firefox/3.6.12"

This is very useful when are writing scripts to get only the HTTP status code.

References –

How to share your terminal session with another user in real time.

Linux has a script command which is mainly used for ‘typescripting’ all output printed on terminal. Commands typed on a terminal and the resulting output can be written to a file for later retrieval.

One little known use of the script command is for sharing your terminal session with another user, this would particularly be useful for telecooperation say between a user and instructor. The instructor can lead the session by executing commands on the shell while the student would observe. Here is one way of doing this –

1. Instructor creates a named pipe using mkfifo

instructor@linubuvma:/$ mkfifo /tmp/shared-screen

instructor@linubuvma:/$ ls -al /tmp/shared-screen 
prw-rw-r-- 1 instructor instructor 0 Mar 31 00:08 /tmp/shared-screen

instructor@linubuvma:/$ script -f /tmp/shared-screen 

2. Student views the session in real time by reading the shared-screen file –

student@linubuvma:/tmp$ cat shared-screen
Script started on Fri 31 Mar 2017 12:09:42 AM EDT

As soon as the student runs the

cat shared-screen

command, the script command also gets started on the instructor’s session.

Whatever is typed on the instructor’s terminal will show up on the student’s screen and the student’s terminal will be restored as soon as the instructor exits or terminates the script session –

instructor@linubuvma:/$ free -m
             total       used       free     shared    buffers     cached
Mem:          3946       3572        374         40        288        996
-/+ buffers/cache:       2288       1658
Swap:         4092        195       3897
instructor@linubuvma:/$ exit

Script done on Fri 31 Mar 2017 12:12:02 AM EDT

Note – the student’s screen will show the user id of the instructor at the bash prompt, as it is a replica of the instructors session. Once the instructor terminates the session, the student will get back to their original bash prompt.