Record your bash shell and upload as a gif file

Recording a video when you are typing is all but a waste of resources so I set out on a quest to find the easiest way to record my bash and convert that recording to a gif file that can be posted on wordpress without having to ‘upgrade’ to upload your ‘video’

I came across several solutions
ttystudio
ttygif
seq2gif

but only one offered me a hassle-free experience was asciinema.
The recordings can be made locally or put online instantly. To convert to a gif file you can use asciinema2gif to generate one and you are done with it.
Now you have your recording as a gif.

the asciinema project
the assciinema2gif project

to record a file you type
asciinema rec [filename]
The recording finishes whet typing exit or pressing ctrl+d.
Use a filename if you want to store it locally

Available options:

  • -c, --command= – Specify command to record, defaults to $SHELL
  • -t, --title= – Specify the title of the asciicast
  • -w, --max-wait= – Reduce recorded terminal inactivity to max seconds
  • -y, --yes – Answer “yes” to all prompts (e.g. upload confirmation)
  • -q, --quiet – Be quiet, suppress all notices/warnings (implies -y)
patrick@debian:~/utils$ mkdir ~/utils;cd ~/utils
patrick@debian:~/utils$ git clone --recursive https://github.com/asciinema/asciicast2gif.git
Cloning into 'asciicast2gif'...
remote: Counting objects: 296, done.
remote: Compressing objects: 100% (153/153), done.
remote: Total 296 (delta 145), reused 269 (delta 118), pack-reused 0
Receiving objects: 100% (296/296), 65.03 KiB | 0 bytes/s, done.
Resolving deltas: 100% (145/145), done.
Submodule 'asciinema-player' (https://github.com/asciinema/asciinema-player.git) registered for path 'asciinema-player'
Cloning into '/home/patrick/utils/asciicast2gif/asciinema-player'...
remote: Counting objects: 4425, done.
remote: Total 4425 (delta 0), reused 0 (delta 0), pack-reused 4425
Receiving objects: 100% (4425/4425), 1.56 MiB | 1016.00 KiB/s, done.
Resolving deltas: 100% (2144/2144), done.
Submodule path 'asciinema-player': checked out 'f487580ca161a52bb34613d39e1b27df4ae1642a'
patrick@debian:~/utils$ ls
asciicast2gif

patrick@debian:~/utils$ git clone https://github.com/asciinema/asciinema.git
Cloning into 'asciinema'...
remote: Counting objects: 2682, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 2682 (delta 0), reused 0 (delta 0), pack-reused 2679
Receiving objects: 100% (2682/2682), 1.57 MiB | 936.00 KiB/s, done.
Resolving deltas: 100% (1341/1341), done.
patrick@debian:~/utils$ cd asciinema/
patrick@debian:~/utils/asciinema$ ls
asciinema CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md doc Dockerfile LICENSE Makefile man README.md setup.cfg setup.py tests Vagrantfile
patrick@debian:~/utils/asciinema$ python3 -m asciinema --version
asciinema 1.4.0
patrick@debian:~/utils/asciinema$ git pull
Already up-to-date.
patrick@debian:~/utils/asciinema$ cd ../asciicast2gif/;git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
patrick@debian:~/utils/asciicast2gif$

To be sure you have the latest version don’t forget to git pull in the asciinema directory.

To launch asciinema with python 3 you need to have the path in your pythonpath environment variable at startup so edit your bashrc script and put in the export bit

patrick@debian:~/casts$ echo $PYTHONPATH
patrick@debian:~/casts$ export PYTHONPATH=$PYTHONPATH:~/utils/:~/utils/asciinema/
patrick@debian:~/casts$ echo $PYTHONPATH
:/home/patrick/utils/:/home/patrick/utils/asciinema/

For fun I recorded this with asciinema here asciinema recording

And for more fun I converted it to a gif file for yours truly with asciicast2gif

click on it to view properly

asciinema_create

I also recorded how to install docker and run asciicast2gif. Enjoy my tinkering
Creating a Gif file from you asciinema recording

patrick@debian:~/utils/asciicast2gif$ cd ../../casts/;wget https://asciinema.org/a/e46k1qs5dqgru7mwfygvj969c.json
--2017-05-16 19:46:35-- https://asciinema.org/a/e46k1qs5dqgru7mwfygvj969c.json
Resolving asciinema.org (asciinema.org)... 109.107.38.78
Connecting to asciinema.org (asciinema.org)|109.107.38.78|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://s3-eu-west-1.amazonaws.com/asciinema-bb-eu/uploads/asciicast/file/120837/asciicast.json?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAI2DOCAQ34YNJM3GA%2F20170516%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20170516T174635Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=89ffdb5c583822b47c500336077a1897baf63263819cb1790b4cbb7ed1396248 [following]
--2017-05-16 19:46:35-- https://s3-eu-west-1.amazonaws.com/asciinema-bb-eu/uploads/asciicast/file/120837/asciicast.json?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAI2DOCAQ34YNJM3GA%2F20170516%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20170516T174635Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=89ffdb5c583822b47c500336077a1897baf63263819cb1790b4cbb7ed1396248
Resolving s3-eu-west-1.amazonaws.com (s3-eu-west-1.amazonaws.com)... 54.231.130.20
Connecting to s3-eu-west-1.amazonaws.com (s3-eu-west-1.amazonaws.com)|54.231.130.20|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 323617 (316K) [application/json]
Saving to: ‘e46k1qs5dqgru7mwfygvj969c.json’
e46k1qs5dqgru7mwfygvj969c.json 100%[==========================================================================================================================================>] 316.03K 1.20MB/s in 0.3s
2017-05-16 19:46:36 (1.20 MB/s) - ‘e46k1qs5dqgru7mwfygvj969c.json’ saved [323617/323617]
FINISHED --2017-05-16 19:46:36--
Total wall clock time: 0.8s
Downloaded: 1 files, 316K in 0.3s (1.20 MB/s)

patrick@debian:~/casts$ mv e46k1qs5dqgru7mwfygvj969c.json installing_using_asciicast2gif.json
patrick@debian:~/casts$ sudo docker run --rm -v $PWD:/data asciinema/asciicast2gif -s 2 -t solarized-dark installing_using_asciicast2gif.json installing_using_asciicast2gif.gif
[sudo] password for patrick:
==> Loading installing_using_asciicast2gif.json...
==> Spawning PhantomJS renderer...
==> Generating frame screenshots...

You can see some more info on your docker image use the following command

patrick@debian:~$ sudo docker images
[sudo] password for patrick:
Sorry, try again.
[sudo] password for patrick:
REPOSITORY TAG IMAGE ID CREATED SIZE
asciinema/asciicast2gif latest 7589ae2fca68 9 days ago 832 MB

Docker stores these images in layers in /var/lib/docker/overlay2#

root@debian:/var/lib/docker# du -sh overlay2/
845M overlay2/

but that is something for another article on docker
more on Docker on Debian.org

switching keyboard layouts on debian

As are perhaps many people I sometimes use a qwerty keyboard and sometimes I’m using an azerty keyboard and/or maybe you want qwerty on an azerty due to typing habits etc.
So yes you want to change the layout asap

patrick@debian:~$ cat /etc/default/locale 
#  File generated by update-locale
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"

so that is what you are using on your system right now. I want to switch to a belgian azerty so I make sure I have the goods

patrick@debian:~$ sudo apt-get install console-data unicode-data

Now reconfigure your locales and you will be presented with a prompt where you can check the layouts you need.

patrick@debian:~$ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
  en_US.UTF-8... done
  nl_BE.ISO-8859-1... done
  nl_BE.UTF-8... done
  nl_BE.ISO-8859-15@euro... done
Generation complete.

Now just set it in bash..

patrick@debian:~$ setxkbmap be

System wide I still have en_US set

patrick@debian:~$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

You can see this here as well

patrick@debian:~$ cat /etc/default/keyboard 
# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""

BACKSPACE="guess"

So you could now set this command in a startup bash script. Systemwide you can do this in /etc/profile
or you can execute the command below, it will also give you the opportunity to set some other options like what your alt key does and the symbol key (commonly known as a winkey or superkey)

patrick@debian:~$ cat /etc/default/keyboard 
# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="be"
XKBVARIANT=""
XKBOPTIONS="lv3:ralt_switch,compose:lwin,terminate:ctrl_alt_bksp"

BACKSPACE="guess"

Allright have fun 🙂

additional information: https://wiki.debian.org/Keyboard

Generate a sources.list file online

A neat site where you can just go and generate some sources.list entries to your liking. For example I generated this by selecting Belgium, the testing distribution and a couple of software projects I like:

#——————————————————————————#
# OFFICIAL DEBIAN REPOS
#——————————————————————————#

###### Debian Main Repos
deb http://ftp.be.debian.org/debian/ testing main contrib non-free
deb-src http://ftp.be.debian.org/debian/ testing main contrib non-free

deb http://ftp.be.debian.org/debian/ testing-updates main contrib non-free
deb-src http://ftp.be.debian.org/debian/ testing-updates main contrib non-free

deb http://security.debian.org/ testing/updates main
deb-src http://security.debian.org/ testing/updates main

#——————————————————————————#
# UNOFFICIAL REPOS
#——————————————————————————#

###### 3rd Party Binary Repos
###Debian Multimedia
deb http://www.deb-multimedia.org testing main non-free

###DotDeb
deb http://packages.dotdeb.org stable all

deb-src http://packages.dotdeb.org stable all

###Google Chrome Browser
deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main

###Mozilla Firefox Aurora
deb http://mozilla.debian.net/ experimental firefox-aurora

###Steam
deb [arch=i386,amd64] http://repo.steampowered.com/steam/ precise steam

###TOR
deb [arch=i386,amd64,armel,armhf] http://deb.torproject.org/torproject.org stretch main
deb-src [arch=i386,amd64,armel,armhf] http://deb.torproject.org/torproject.org wheezy main

You can try it out on Debian Sources List Generator
This site is gradually moving to the domain http://www.debgen.org/



Others are
Debgen.xyz

Note use it as an inspiration for adding something, never copy paste from a web page to your terminal 🙂

To understand the format better visit this site: Debian Repository Format

install a local .deb file

You can install a local .deb file (one you downloaded or built on your own system) by doing

sudo dpkg -i filename.deb

or by install gdebi and doing

sudo gdebi filename.deb

This way your dependencies are handled and all is well

gdebi

To see what packages you installed manually go to your synaptic package manager and click on status “installed local or obsolete”

peek9CXA0Y

prioritize your repositories with apt-pinning

files that are used on this topic are

patrick@stretch:~$ ls /etc/apt/apt.conf.d/70debconf /etc/apt/sources.list /etc/apt/sources.list.d /etc/apt/preferences.d/
/etc/apt/apt.conf.d/70debconf  /etc/apt/sources.list

/etc/apt/preferences.d/:
external.pref  stretch_main.pref  stretch_security_updates.pref  unstable.pref

/etc/apt/sources.list.d:
external.list  stretch_main.list  stretch_security_updates.list  unstable.list

To understand the format better visit this site: Debian Repository Format

You can just have the repositories in the sources.list file but it is recommended to create them seperately in the sources.list.d directory.
Then create equally named .pref files in the preference.d directory.

It’s a good thing to understand the meaning of the priority numbers apt uses by default so you don’t get confused along the way when you see them popup:

in short
If the target release has been specified then APT uses the following algorithm to set the priorities of the versions of a package. Assign:

priority 100
to the version that is already installed (if any).
priority 500
to the versions that are not installed and do not belong to the target release.
priority 990
to the versions that are not installed and belong to the target release.

If the target release has not been specified then APT simply assigns priority 100 to all installed package versions and priority 500 to all uninstalled package versions.

Now you know what the default priority numbers are you can set your own in your example.pref file according to the apt algorithm:

How Apt Interprets Priorities

Priorities (P) assigned in the APT preferences file must be positive or negative integers. They are interpreted as follows (roughly speaking):

P > 1000
causes a version to be installed even if this constitutes a downgrade of the package.
990 < P <=1000
causes a version to be installed even if it does not come from the target release, unless the installed version is more recent.
500 < P <=990
causes a version to be installed unless there is a version available belonging to the target release or the installed version is more recent.
100 < P <=500
causes a version to be installed unless there is a version available belonging to some other distribution or the installed version is more recent.
0 < P <=100
causes a version to be installed only if there is no installed version of the package.
P < 0
prevents the version from being installed.

I am currently using stretch RC2 which is at the time of this writing still a testing distribution. It is highly recommended not to use unstable packages as they well aren’t tested. If you download a package from a testing repository then you’re downloading a package that has been bugfree for 10 consecutive days. However if it is a desktop and you are okay with destroying it to the point of no recovery then you can use it like I do.

I highly recommend you read through the manual on your distribution

man 5 apt_preferences

This is what I’ve got
in my sources file, note that everything is commented out here or I would have a conflict with my files in the sources.list.d directory

patrick@stretch:~$ cat /etc/apt/sources.list
# 

# deb cdrom:[Debian GNU/Linux stretch-DI-rc2 _Stretch_ - Official Snapshot amd64 DVD Binary-1 20170201-11:49]/ stretch contrib main

#deb cdrom:[Debian GNU/Linux stretch-DI-rc2 _Stretch_ - Official Snapshot amd64 DVD Binary-1 20170201-11:49]/ stretch contrib main

#deb http://ftp.belnet.be/debian/ stretch main
#deb-src http://ftp.belnet.be/debian/ stretch main

#deb http://security.debian.org/debian-security stretch/updates main contrib
#deb-src http://security.debian.org/debian-security stretch/updates main contrib

#deb http://ftp.belnet.be/debian/ sid main
#deb http://ftp.belnet.be/debian/ sid contrib non-free
patrick@stretch:~$ ls /etc/apt/sources.list.d/*
/etc/apt/sources.list.d/external.list
/etc/apt/sources.list.d/stretch_main.list
/etc/apt/sources.list.d/stretch_security_updates.list
/etc/apt/sources.list.d/unstable.list

patrick@stretch:~$ cat /etc/apt/sources.list.d/*
# Debian 3rd party repositories
deb http://apt.insynchq.com/debian stretch non-free contrib
deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main
# -----------------------------
# Stretch main package repos
deb http://ftp.belnet.be/debian/ stretch main
deb-src http://ftp.belnet.be/debian/ stretch main
# ----------------------------
# Stretch security packages repositories
deb http://security.debian.org/debian-security stretch/updates main contrib
deb-src http://security.debian.org/debian-security stretch/updates main contrib
# -----------------------------------
# Debian Unstable repos (sid)
deb http://ftp.belnet.be/debian/ sid main
deb http://ftp.belnet.be/debian/ sid contrib non-free
# ---------------------------
patrick@stretch:~$

Note that my stretch repository is atm a testing repository as stretch is being tested. As soon as Stretch is officially released it will become a stable repository.. That is why I don’t have a testing repository in this setup 🙂

patrick@stretch:~$ ls /etc/apt/sources.list.d/*
/etc/apt/sources.list.d/external.list
/etc/apt/sources.list.d/stretch_main.list
/etc/apt/sources.list.d/stretch_security_updates.list
/etc/apt/sources.list.d/unstable.list

patrick@stretch:~$ cat /etc/apt/preferences.d/*Package: *
Pin: release a=external
Pin-Priority: 500
Package: *
Pin: release a=stretch_main
Pin-Priority: 900
Package: *
Pin: release l=Debian-Security
Pin-Priority: 1000
Package: *
Pin: release a=unstable
Pin-Priority: 50

When you’re done adjusting those list or pref files don’t forget to do sudo apt-get update to have your config recognized.

In this example you can see I set the unstable repository to a priority of 50

patrick@stretch:/etc/apt/sources.list.d$ sudo apt-cache policy adduser
[sudo] wachtwoord voor patrick:
adduser:
  Geïnstalleerd: 3.115
  Kandidaat:     3.115
  Versietabel:
 *** 3.115 990
        990 http://ftp.belnet.be/debian stretch/main amd64 Packages
         50 http://ftp.belnet.be/debian sid/main amd64 Packages
        100 /var/lib/dpkg/status
patrick@stretch:~$ sudo apt-cache policy
Pakketbestanden:
 100 /var/lib/dpkg/status
     release a=now
  50 http://ftp.belnet.be/debian sid/non-free amd64 Packages
     release o=Debian,a=unstable,n=sid,l=Debian,c=non-free,b=amd64
     origin ftp.belnet.be
  50 http://ftp.belnet.be/debian sid/contrib amd64 Packages
     release o=Debian,a=unstable,n=sid,l=Debian,c=contrib,b=amd64
     origin ftp.belnet.be
  50 http://ftp.belnet.be/debian sid/main amd64 Packages
     release o=Debian,a=unstable,n=sid,l=Debian,c=main,b=amd64
     origin ftp.belnet.be
 990 http://ftp.belnet.be/debian stretch/main amd64 Packages
     release o=Debian,a=testing,n=stretch,l=Debian,c=main,b=amd64
     origin ftp.belnet.be
 500 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages
     release v=1.0,o=Google, Inc.,a=stable,n=stable,l=Google,c=main,b=amd64
     origin dl.google.com
 990 http://apt.insynchq.com/debian stretch/contrib amd64 Packages
     release o=Insynchq, Inc.,n=stretch,l=Insynchq, Inc.,c=contrib,b=amd64
     origin apt.insynchq.com
 990 http://apt.insynchq.com/debian stretch/non-free amd64 Packages
     release o=Insynchq, Inc.,n=stretch,l=Insynchq, Inc.,c=non-free,b=amd64
     origin apt.insynchq.com
Vastgepinde pakketten:

Note that the debian stretch repositories are set to 990 even though I set otherwise in my own pref files.. Now why is that?

Well it is because that is what is set as my default target release in the file
/etc/apt/apt.conf.d/70debconf

patrick@stretch:~$ cat /etc/apt/apt.conf.d/
00CDMountPoint         20auto-upgrades        50unattended-upgrades
00trustcdrom           20listchanges          60gnome-software
01autoremove           20packagekit           70debconf
01autoremove-kernels   50appstream
patrick@stretch:~$ cat /etc/apt/apt.conf.d/70debconf
// Pre-configure all packages with debconf before they are installed.
// If you don't like it, comment it out.
DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt || true";};
APT::Default-Release "stretch";
APT::Cache-Limit 100000000;
Apt::Get::Purge;
//had problems with running MMap runs out of room, so add cache-limit//
//APT::Cache-Limit "25165824";
//Server down takes too long, add timout
Acquire::http::Timeout "3";
Acquire::ftp::Timeout "3";

If I didn’t have the distro code “stretch” configured in my sources I could have configured it this way if I wanted to continuesly use the testing repositories even when stretch was officially released as a stable distro:

deb http://security.debian.org testing/updates main contrib non-free
deb-src http://security.debian.org testing/updates main contrib non-free

Do sudo apt-get update && sudo apt-get dist-upgrade to update your system on a regular basis.

if in doubt once more read the fine manual
TLDR,RTFM:

man 5 apt_preferences

When you run “apt-get -t unstable install foo”, this sets APT::Default-Release for this invocation of apt-get, but it doesn’t affect future runs. This is useful in some circumstances, but problematic in others
You can also leave the -t flag and do it this way using a forward slash

apt-get install pkgname1/stable pkgname2/stable

PS: All your sources in /etc/apt/sources.list.d are compiled to a single list in the /var/lib/apt/ directory
If you ever have a problem with that file you can rename the lists file to lists.old or something and the regenerate the file with apt-get update

patrick@debian:/var/lib/apt$ ls -ahl
total 144K
drwxr-xr-x  6 root root 4.0K May 16 12:06 .
drwxr-xr-x 61 root root 4.0K May 15 18:10 ..
-rw-r--r--  1 root root  269 Apr 20  2016 cdroms.list
-rw-r--r--  1 root root  269 Apr 20  2016 cdroms.list~
-rw-r--r--  1 root root    0 May 16 10:25 daily_lock
-rw-r--r--  1 root root  76K May 16 00:47 extended_states
drwxr-xr-x  3 root root  20K May 16 12:06 lists
drwxr-xr-x  3 root root  20K May 15 17:33 lists.old
drwxr-xr-x  3 root root 4.0K Apr 20  2016 mirrors
drwxr-xr-x  2 root root 4.0K Sep 15  2015 periodic

Sources

Debian SourcesList
Debian Testing