Thursday 31 August 2017

Adding color to your commands with tput and echo



In a previous article I demonstrated how we could modify the color of the text being displayed on the command line using printf and ANSI escape sequences.

In this article, using those same escape codes I'll show you how we would use echo instead of printf and also use the tput command to change color.

While working with printf in the previous article I printed out some random text but here we'll be using command line substitution to add color to commands.

Before the examples, let's have a look at the ANSI escape sequences reference table:


Now, let's look at the first example using echo:

[root@pbox ~]# echo -e "\033[34m$(cat list)\033[00m"



The equivalent printf rendition would be as follows:

printf "\033[34m$(cat list)\033[00m"


Next we have a look at tput. The tput command in a nutshell gives the shell the ability to access and modify values of some of the terminal dependent capabilities.

tput setaf 3 ; cat /etc/hosts;tput setaf 7



Using the tput command with the setaf option and giving it the argument 3 gives the subsequent typed commands a yellow color. Setting the value to 7 returns the tex color to the default white.

I took screenshots of how the text changed color as I changed the numeric value of the argument being passed to tput setaf



We dived into a small subset of tput's capabilities. Consider going through this link to learn more about tput.

I've been told that tput's behavior is not consistent across platforms. So if you want to use color coded content in your scripts I'd recommend sticking to echo and printf in the interest of portability of the code.

Tar and untar files simultaneously in a single command


In this quick article I'll demonstrate how we can perform a tar and untar operation on a file or directory simultaneously. We'll be looking at two scenarios. The first will be archiving and extracting the file in a different folder on the same server and a second scenario to archive and extract files on a different server using ssh. Additionally we'll brief look at subshells in bash.

The one liner command for the first scenario is as follows:

tar -cvf - python-jinja2-28-2.8-1.el7.R.noarch.rpm | (cd /tmp/; tar xvf -)


This will perform a tar of the file python-jinja2-28-2.8-1.el7.R.noarch.rpm and the generated output of this command i.e. the tar archive will be piped to the input of the next tar command to extract the archive. The first dash (-) here tells tar to send it's output to stdout instead of a file. the second dash(-) with the tar command tells tar to read it's input from stdin being piped to it instead of a file. This is not a shell construct and does not work with all commands. I've known it to work with file, cat and diff command though.

The interesting part in the tar happens after the pipe. By using parenthesis i.e. () , we invoke the commands within the parenthesis in a sub shell. The subshell executes the commands enclosed within parenthesis simultaneously and exits and we get our old shell back. So after I run the command I don't end up in /tmp directory when the command finishes. I remain in my present working directory.

The parenthesis groups the commands and executes them as a single unit. We often use parenthesis for command grouping bu there's another method available for grouping commands like this would invoking a subshell and that is via curly braces {}. This involves placing the commands to be executed within curly braces and the last command must have a semicolon following it. Here's an example:

[root@pbox ~]# { cd /tmp; ls -l; pwd; }




Here' s a screenshot of what went down when I ran the tar command one liner:




Now this trick only appears to work if I use dashes to substitute the archive name.

In the second scenario we do the same thing but this time on a different server via ssh. Here's the command.

tar -cvf - python-jinja2-28-2.8-1.el7.R.noarch.rpm | ssh root@192.168.188.133 "(cd /tmp/; tar xvf -)"


This indeed archives the file on the source server and then extracts it on the destination server.

Wednesday 30 August 2017

Removing files with spaces in their names in Linux (using IFS)

In UNIX it's uncommon to have files with spaces but it can happen. Consider a situation wherein I have a couple of space separated files and I'd like to remove some of them.

[root@pbox test]# ls -l
total 0
drwxr-xr-x. 2 root root 6 Aug 30 14:25 abc
drwxr-xr-x. 2 root root 6 Aug 30 14:25 def
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Nov  7  2017 my file 4
-rw-r--r--. 1 root root 0 Nov  7  2020 my file 5
-rw-r--r--. 1 root root 0 Nov  7  2017 my file 6
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7

I'd like to remove files modified in the month of August.

[root@pbox test]# ls -l |grep -i ^-|grep -i Aug
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7


Now if I try to run the for loop to iterate over the required files I get an unexpected result because of the spaces:

[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do echo "$file to remove is $i" ; done
 to remove is my
 to remove is file
 to remove is 1
 to remove is my
 to remove is file
 to remove is 2
 to remove is my
 to remove is file
 to remove is 3
 to remove is my
 to remove is file
 to remove is 7


This is because the default input field separator is a space character so whenever the for loop sees a space it treats the following string as a new field.

To fix this we'll modify our input field separator by changing the value of the IFS variable.


[root@pbox test]# IFS=$'\n'
[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do echo "$file to remove is $i" ; done
 to remove is my file 1
 to remove is my file 2
 to remove is my file 3
 to remove is my file 7
[root@pbox test]#

Now instead of doing an echo if we'd like to remove the files we could simply type the following:

[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do rm $i ; done
rm: remove regular empty file ‘my file 1’? y
rm: remove regular empty file ‘my file 2’? y
rm: remove regular empty file ‘my file 3’? y
rm: remove regular empty file ‘my file 7’? y

And the files are now gone.

[root@pbox test]# ls -ltr
total 0
drwxr-xr-x. 2 root root 6 Aug 30 14:25 def
drwxr-xr-x. 2 root root 6 Aug 30 14:25 abc
-rw-r--r--. 1 root root 0 Nov  7  2017 my file 4
-rw-r--r--. 1 root root 0 Nov  7  2017 my file 6
-rw-r--r--. 1 root root 0 Nov  7  2020 my file 5

Add a new line after a string match using vim or sed

In this brief article I'd like to demonstrate how we can add a new line after a character match using vim and sed.

Let's take an example scenario where I have a file comprised of the 'ls -l' output of the /etc/ directory and I would like to insert a new line between each line in the command output.

My file looks like this:

[ssuri@:~] $ cat dir_list | head
drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d
drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly
drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11
drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg
drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal
drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm
drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg
drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d
drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d
drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb


First let's insert a new line using vim. The vim command used here is :%s/^drw/\rdrw/g

The output of this vim command will modify the file as follows:


  2 drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d
  3
  4 drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly
  5
  6 drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11
  7
  8 drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg
  9
 10 drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal
 11
 12 drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm
 13
 14 drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg
 15
 16 drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d
 17
 18 drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d
 19
 20 drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb

(Don't mind the line numbers. they're just there because I had the set nu flag on to show line numbers)

Let me break down the expression for you.

% -> operates on the entire file.
s  -> search for an expression.
^drw -> search for lines beginning with the string drw.
\rdrw -> \r is the carriage return. In vim this will insert a new line. 
g -> Perform a global search and replace.


So, the expression %s/^drw/\rdrw/g will walk through the entire file, look for the lines beginning with the string drw and replace them with a new line followed the line beginning with the string drw throughout the file.


Using vim is great but you'll have to manually edit the file. So let's look at sed if you'd like to accomplish this task within a script.


[ssuri@:~] $ sed 's/^drw/\ndrw/g' dir_list

drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d

drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly

drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11

drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg

drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal

drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm

drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg

drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d

drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d

drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb


The sed expression is very similar to the expression we used in vim the only difference being that in case of sed we'll use \n to insert a new line instead of \r.

I hope this article was useful to you and I thank you for reading.

Saturday 26 August 2017

Converting text on CLI to images using ImageMagick



In this article I'll demonstrate how we can convert the output of commands we type on the Linux command line to images using ImageMagick software. This software allows users to create and modify images. It's generally meant for use in an X windows environment but we'll be using it purely on the command line for the purposes of this article.

The ImageMagick software is not installed on Linux distributions by default but is available in the base repo so you don't have to search around for it.

Let's begin by installing the package.

[root@walk ~]# yum search ImageMagick
Loaded plugins: fastestmirror, security
Determining fastest mirrors
epel/metalink                                                                                                | 5.7 kB     00:00
 * base: ftp.iitm.ac.in
 * epel: ftp.yz.yamagata-u.ac.jp
 * extras: ftp.iitm.ac.in
 * jpackage-generic: sunsite.informatik.rwth-aachen.de
 * updates: ftp.iitm.ac.in
base                                                                                                         | 3.7 kB     00:00
epel                                                                                                         | 4.3 kB     00:00
epel/primary_db                                                                                              | 5.9 MB     01:15
extras                                                                                                       | 3.4 kB     00:00
jpackage-generic                                                                                             | 1.9 kB     00:00
spacewalk                                                                                                    | 2.1 kB     00:00
updates                                                                                                      | 3.4 kB     00:00
updates/primary_db                                                                                           | 3.1 MB     00:12
===================================================== N/S Matched: ImageMagick =====================================================
ImageMagick-c++.i686 : ImageMagick Magick++ library (C++ bindings)
ImageMagick-c++.x86_64 : ImageMagick Magick++ library (C++ bindings)
ImageMagick-c++-devel.i686 : C++ bindings for the ImageMagick library
ImageMagick-c++-devel.x86_64 : C++ bindings for the ImageMagick library
ImageMagick-devel.i686 : Library links and header files for ImageMagick app development
ImageMagick-devel.x86_64 : Library links and header files for ImageMagick app development
ImageMagick-doc.x86_64 : ImageMagick html documentation
ImageMagick-perl.x86_64 : ImageMagick perl bindings
GraphicsMagick.i686 : An ImageMagick fork, offering faster image generation and better quality
GraphicsMagick.x86_64 : An ImageMagick fork, offering faster image generation and better quality
ImageMagick.i686 : An X application for displaying and manipulating images
ImageMagick.x86_64 : An X application for displaying and manipulating images
php-magickwand.x86_64 : PHP API for ImageMagick
php-pecl-imagick.x86_64 : Provides a wrapper to the ImageMagick library

  Name and summary matches only, use "search all" for everything.

  
[root@walk ~]# yum install ImageMagick -y
Loaded plugins: fastestmirror, security
Setting up Install Process
Loading mirror speeds from cached hostfile
 * base: ftp.iitm.ac.in
 * epel: ftp.yz.yamagata-u.ac.jp
 * extras: ftp.iitm.ac.in
 * jpackage-generic: sunsite.informatik.rwth-aachen.de
 * updates: ftp.iitm.ac.in
Resolving Dependencies
--> Running transaction check
---> Package ImageMagick.x86_64 0:6.7.2.7-6.el6 will be installed
--> Processing Dependency: libwmflite-0.2.so.7()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libwmf-0.2.so.7()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: librsvg-2.so.2()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libltdl.so.7()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libImath.so.6()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libIlmThread.so.6()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libIlmImf.so.6()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libIex.so.6()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Processing Dependency: libHalf.so.6()(64bit) for package: ImageMagick-6.7.2.7-6.el6.x86_64
--> Running transaction check
---> Package OpenEXR-libs.x86_64 0:1.6.1-8.1.el6 will be installed
---> Package ilmbase.x86_64 0:1.0.1-6.1.el6 will be installed
---> Package librsvg2.x86_64 0:2.26.0-14.el6 will be installed
--> Processing Dependency: libgsf >= 1.6.0 for package: librsvg2-2.26.0-14.el6.x86_64
--> Processing Dependency: libgsf-1.so.114()(64bit) for package: librsvg2-2.26.0-14.el6.x86_64
--> Processing Dependency: libcroco-0.6.so.3()(64bit) for package: librsvg2-2.26.0-14.el6.x86_64
---> Package libtool-ltdl.x86_64 0:2.2.6-15.5.el6 will be installed
---> Package libwmf.x86_64 0:0.2.8.4-25.el6_7 will be installed
---> Package libwmf-lite.x86_64 0:0.2.8.4-25.el6_7 will be installed
--> Running transaction check
---> Package libcroco.x86_64 0:0.6.2-5.el6 will be installed
---> Package libgsf.x86_64 0:1.14.15-5.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

====================================================================================================================================
 Package                          Arch                       Version                                 Repository                Size
====================================================================================================================================
Installing:
 ImageMagick                      x86_64                     6.7.2.7-6.el6                           base                     1.9 M
Installing for dependencies:
 OpenEXR-libs                     x86_64                     1.6.1-8.1.el6                           base                     197 k
 ilmbase                          x86_64                     1.0.1-6.1.el6                           base                      72 k
 libcroco                         x86_64                     0.6.2-5.el6                             base                     100 k
 libgsf                           x86_64                     1.14.15-5.el6                           base                     116 k
 librsvg2                         x86_64                     2.26.0-14.el6                           base                     140 k
 libtool-ltdl                     x86_64                     2.2.6-15.5.el6                          base                      44 k
 libwmf                           x86_64                     0.2.8.4-25.el6_7                        base                     132 k
 libwmf-lite                      x86_64                     0.2.8.4-25.el6_7                        base                      51 k

Transaction Summary
====================================================================================================================================
Install       9 Package(s)

Total download size: 2.7 M
Installed size: 9.8 M
Downloading Packages:
(1/9): ImageMagick-6.7.2.7-6.el6.x86_64.rpm                                                                  | 1.9 MB     00:07
(2/9): OpenEXR-libs-1.6.1-8.1.el6.x86_64.rpm                                                                 | 197 kB     00:03
(3/9): ilmbase-1.0.1-6.1.el6.x86_64.rpm                                                                      |  72 kB     00:00
(4/9): libcroco-0.6.2-5.el6.x86_64.rpm                                                                       | 100 kB     00:00
(5/9): libgsf-1.14.15-5.el6.x86_64.rpm                                                                       | 116 kB     00:00
(6/9): librsvg2-2.26.0-14.el6.x86_64.rpm                                                                     | 140 kB     00:01
(7/9): libtool-ltdl-2.2.6-15.5.el6.x86_64.rpm                                                                |  44 kB     00:00
(8/9): libwmf-0.2.8.4-25.el6_7.x86_64.rpm                                                                    | 132 kB     00:00
(9/9): libwmf-lite-0.2.8.4-25.el6_7.x86_64.rpm                                                               |  51 kB     00:00
------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                               111 kB/s | 2.7 MB     00:25
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Warning: RPMDB altered outside of yum.
  Installing : ilmbase-1.0.1-6.1.el6.x86_64                                                                                     1/9
  Installing : libwmf-lite-0.2.8.4-25.el6_7.x86_64                                                                              2/9
  Installing : libwmf-0.2.8.4-25.el6_7.x86_64                                                                                   3/9
  Installing : OpenEXR-libs-1.6.1-8.1.el6.x86_64                                                                                4/9
  Installing : libtool-ltdl-2.2.6-15.5.el6.x86_64                                                                               5/9
  Installing : libgsf-1.14.15-5.el6.x86_64                                                                                      6/9
  Installing : libcroco-0.6.2-5.el6.x86_64                                                                                      7/9
  Installing : librsvg2-2.26.0-14.el6.x86_64                                                                                    8/9
  Installing : ImageMagick-6.7.2.7-6.el6.x86_64                                                                                 9/9
  Verifying  : libwmf-lite-0.2.8.4-25.el6_7.x86_64                                                                              1/9
  Verifying  : librsvg2-2.26.0-14.el6.x86_64                                                                                    2/9
  Verifying  : ImageMagick-6.7.2.7-6.el6.x86_64                                                                                 3/9
  Verifying  : libwmf-0.2.8.4-25.el6_7.x86_64                                                                                   4/9
  Verifying  : libcroco-0.6.2-5.el6.x86_64                                                                                      5/9
  Verifying  : OpenEXR-libs-1.6.1-8.1.el6.x86_64                                                                                6/9
  Verifying  : libgsf-1.14.15-5.el6.x86_64                                                                                      7/9
  Verifying  : libtool-ltdl-2.2.6-15.5.el6.x86_64                                                                               8/9
  Verifying  : ilmbase-1.0.1-6.1.el6.x86_64                                                                                     9/9

Installed:
  ImageMagick.x86_64 0:6.7.2.7-6.el6

Dependency Installed:
  OpenEXR-libs.x86_64 0:1.6.1-8.1.el6       ilmbase.x86_64 0:1.0.1-6.1.el6              libcroco.x86_64 0:0.6.2-5.el6
  libgsf.x86_64 0:1.14.15-5.el6             librsvg2.x86_64 0:2.26.0-14.el6             libtool-ltdl.x86_64 0:2.2.6-15.5.el6
  libwmf.x86_64 0:0.2.8.4-25.el6_7          libwmf-lite.x86_64 0:0.2.8.4-25.el6_7

Complete!
[root@walk ~]#


With the package and it's dependencies installed let's query the rpm to get some information about the package.

[root@walk ~]# rpm -qa | grep -i Image
genisoimage-1.1.9-12.el6.x86_64
ImageMagick-6.7.2.7-6.el6.x86_64
[root@walk ~]# rpm -qi ImageMagick-6.7.2.7-6.el6.x86_64
Name        : ImageMagick                  Relocations: (not relocatable)
Version     : 6.7.2.7                           Vendor: CentOS
Release     : 6.el6                         Build Date: Wed 22 Mar 2017 04:54:38 PM IST
Install Date: Sat 26 Aug 2017 12:35:53 AM IST      Build Host: c1bm.rdu2.centos.org
Group       : Applications/Multimedia       Source RPM: ImageMagick-6.7.2.7-6.el6.src.rpm
Size        : 7321917                          License: ImageMagick
Signature   : RSA/SHA1, Thu 23 Mar 2017 08:28:57 PM IST, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem <http://bugs.centos.org>
URL         : http://www.imagemagick.org/
Summary     : An X application for displaying and manipulating images
Description :
ImageMagick is an image display and manipulation tool for the X
Window System. ImageMagick can read and write JPEG, TIFF, PNM, GIF,
and Photo CD image formats. It can resize, rotate, sharpen, color
reduce, or add special effects to an image, and when finished you can
either save the completed work in the original format or a different
one. ImageMagick also includes command line programs for creating
animated or transparent .gifs, creating composite images, creating
thumbnail images, and more.

ImageMagick is one of your choices if you need a program to manipulate
and display images. If you want to develop your own applications
which use ImageMagick code or APIs, you need to install
ImageMagick-devel as well.


The ImageMagick software provides the convert command which I found very diverse because it allows the user to draw, crop and resize images along with many other things. You can get more information about it by going through the man page.

[root@walk ~]# which convert
/usr/bin/convert
[root@walk ~]#


I intended to use the convert command along with the label feature to pipe out the STDOUT of a command run on the shell to draw that text on an image. 

I tried hard to get this to work but I kept getting the below error while testing.



After a lot of frantic searching I came to know that using the labels feature has been deliberately disabled in RedHat Linux/CentOS systems. I cannot comment on the authenticity of this but after reading it I began to look for alternatives to achieve the desired outcome with convert and without using label.

Finally after a lot of searching I came up with this one liner that did the job:

convert -size 1000x600 -gravity Northwest xc:khaki -font Courier-Bold -fill black  -pointsize 18 -draw "text 5,15 '$(cat /etc/passwd)'" passwd.png


This command generated the following passwd.png image in the current working directory of my CenOS system.


Let's deconstruct the above convert command options:

-size option determines the size of the image.

-gravity option determines the position of text on the image.

-xc option decides the image background or the canvas color.

-font option determines the font type of the text being drawn on the image.

-fill option decides the text color.

-pointsize determines the font size of the text being drawn.

-draw option provides the text to be drawn on the image.


For this demonstration I've done a command substitution of the "fdisk -l" command output to serve as the text to be drawn on the image.

The final parameter passwd.png is the name we'd like for the resulting image.


We can use the list flag with the convert keyword to view the available options for the various flag that we use.

For example:

[root@walk ~]# convert -list font | less
[root@walk ~]#
[root@walk ~]# convert -list gravity
None
Center
East
Forget
NorthEast
North
NorthWest
SouthEast
South
SouthWest
West
Static


Let's take another example changing a few of the options. Let's create an image with the output of "cat /etc/passwd" command.

convert -size 1000x600 -gravity Northwest xc:khaki -font Courier-Bold -fill black  -pointsize 18 -draw "text 5,15 '$(cat /etc/passwd)'" passwd.png




This time I modified the image size, canvas color and font size along with the text to be drawn as I anticipated the output to be larger thereby requiring a larger canvas to display the text.

If we could use labels then the label feature would autosize the text for us to fit on the image.

We can easily change the image format by simply changing the extension of the final image to be created.

To validate, let's create a JPEG image of the df -h command output.

[root@walk ~]# convert -size 700x200 -gravity Northwest xc:white -font Courier-Bold -fill blue  -pointsize 18  -draw "text 5,15 '$(df -h)'" df.jpeg


This command generates the below image:


I hope you found this article useful and perhaps ImageMagick gave you some interesting ideas.

Sunday 13 August 2017

Getting a taste of the AWS command line interface

In this article I'll briefly demonstrate how we can access the AWS command line interface from an EC2 instance.

I've launched an Amazon Linux AMI instance and attached a role to it. I won't go through the entire instance launch wizard but I'll show you the step where I specified the role which is step 3 (Configure instance).


I have created a role of the type Amazon EC2 and attached EC2FullAccess policy with this role as shown in the below screenshot:



This will allow the instance to have access to all EC2 related actions from the AWS command line interface.

I used an IAM role here because the instance I'm using resides in my EC2 environment. In case you want to use AWS cli from an on premises server then you could create an IAM, generate access keys for that user and attach the appropriate policies to that user. You can then install AWS cli on your on premises instance and use the IAM users' access keys for authentication to AWS while running commands.

I chose to build an instance from the Amazon Linux AMI because it comes pre-configured with the AWS cli. But we can install it on other Linux variants fairly easily via pip.


The syntax to run an AWS cli command is as follows:

aws <service> <action>

To use help you can type aws help to get information on available commands for all services or type aws ec2 help to get information on available EC2 related commands only.

Here are examples of the same:

[ec2-user@ip-172-31-23-118 ~]$ aws help | more
AWS()                                                                    AWS()



NAME
       aws -

DESCRIPTION
       The  AWS  Command  Line  Interface is a unified tool to manage your AWS
       services.

SYNOPSIS
          aws [options] <command> <subcommand> [parameters]

       Use aws command help for information on a  specific  command.  Use  aws
       help  topics  to view a list of available help topics. The synopsis for
       each command shows its parameters and their usage. Optional  parameters
       are shown in square brackets.

OPTIONS
       --debug (boolean)

       Turn on debug logging.

       --endpoint-url (string)

       Override command's default URL with the given URL.

       --no-verify-ssl (boolean)

       By  default, the AWS CLI uses SSL when communicating with AWS services.
       For each SSL connection, the AWS CLI will verify SSL certificates. This



[ec2-user@ip-172-31-23-118 ~]$ aws ec2 help | more
EC2()                                                                    EC2()



NAME
       ec2 -

DESCRIPTION
       Amazon  Elastic Compute Cloud (Amazon EC2) provides resizable computing
       capacity in the Amazon Web Services (AWS) cloud. Using Amazon EC2 elim-
       inates your need to invest in hardware up front, so you can develop and
       deploy applications faster.

AVAILABLE COMMANDS
       o accept-reserved-instances-exchange-quote

       o accept-vpc-peering-connection


Now, after viewing the help pages lets run describe-instances command for EC2.

[ec2-user@ip-172-31-23-118 ~]$ aws ec2 describe-instances
You must specify a region. You can also configure your region by running "aws configure".
[ec2-user@ip-172-31-23-118 ~]$

As you may observe from the output we need to run aws configure first to set a few parameters.

[ec2-user@ip-172-31-23-118 ~]$ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: US East
Default output format [None]:
[ec2-user@ip-172-31-23-118 ~]$ aws ec2 describe-instances

Invalid endpoint: https://ec2.US East.amazonaws.com

This throws an error because I wrote the region name incorrectly.
To correct this you could run aws configure again or edit the file ~/.aws/config.

[ec2-user@ip-172-31-23-118 .aws]$ ls
config
[ec2-user@ip-172-31-23-118 .aws]$ cat config
[default]
region = US East


[ec2-user@ip-172-31-23-118 ~]$ cd .aws/
[ec2-user@ip-172-31-23-118 .aws]$ cat config
[default]
region = us-east-1


Now when I run the describe-instances command I should get the desired output.

[ec2-user@ip-172-31-23-118 ~]$ aws ec2 describe-instances | more
{
    "Reservations": [
        {
            "OwnerId": "242386062125",
            "ReservationId": "r-02d7e6663b8d8dde5",
            "Groups": [],
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "ec2-54-147-27-195.compute-1.amazonaws.com",
                    "State": {
                        "Code": 16,
                        "Name": "running"



Now lets view the AWS regions available to us:

[ec2-user@ip-172-31-23-118 ~]$ aws ec2 describe-regions
{
    "Regions": [
        {
            "Endpoint": "ec2.ap-south-1.amazonaws.com",
            "RegionName": "ap-south-1"
        },
        {
            "Endpoint": "ec2.eu-west-2.amazonaws.com",
            "RegionName": "eu-west-2"
        },
        {
            "Endpoint": "ec2.eu-west-1.amazonaws.com",
            "RegionName": "eu-west-1"
        },
        {
            "Endpoint": "ec2.ap-northeast-2.amazonaws.com",
            "RegionName": "ap-northeast-2"
        },
        {
            "Endpoint": "ec2.ap-northeast-1.amazonaws.com",
            "RegionName": "ap-northeast-1"
        },
        {
            "Endpoint": "ec2.sa-east-1.amazonaws.com",
            "RegionName": "sa-east-1"
        },
        {
            "Endpoint": "ec2.ca-central-1.amazonaws.com",
            "RegionName": "ca-central-1"
        },
        {
            "Endpoint": "ec2.ap-southeast-1.amazonaws.com",
            "RegionName": "ap-southeast-1"
        },
        {
            "Endpoint": "ec2.ap-southeast-2.amazonaws.com",
            "RegionName": "ap-southeast-2"
        },
        {
            "Endpoint": "ec2.eu-central-1.amazonaws.com",
            "RegionName": "eu-central-1"
        },
        {
            "Endpoint": "ec2.us-east-1.amazonaws.com",
            "RegionName": "us-east-1"
        },
        {
            "Endpoint": "ec2.us-east-2.amazonaws.com",
            "RegionName": "us-east-2"
        },
        {
            "Endpoint": "ec2.us-west-1.amazonaws.com",
            "RegionName": "us-west-1"
        },
        {
            "Endpoint": "ec2.us-west-2.amazonaws.com",
            "RegionName": "us-west-2"
        }
    ]
}


This concludes this brief but insightful introduction to the AWS command line interface.
I hope this article was helpful to you and I thank you for reading.

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...