The stuff I do

Stuff I forget

Search by tag:
Ansible tips [bash][ansible]

Run a command on several hosts 🔗

The documentation Introduction to Ad Hoc commands is a great reference.

  1. In the inventory file create the list of servers to target
  1. Run the command
ansible [target_group_name] -i path/to/inventory/file -m shell -a [your_command]

# Example
ansible my_target_group_name -i inventories/inventory -m shell -a 'df -h'

The module shell allows to run any shell command but one can use any module

If you need to become root to run the command pass --become to the ansible command.

--becomeBecome root
-u <username>Change the username used
--ask-become-pass or -KPrompts you for the password to use for privilege escalation
-f 10Change how many machines are targeted simultaneously

Copying files between hosts 🔗

Refer to this link

Bash arrays [bash][array]

Initiate an array 🔗

myArray=( element_1 element_2 element_n )

Access item by index 🔗

echo ${myArray[2]}

Iterate through array 🔗

To iterate over the elements:

for element in "${array[@]}"
    echo "$element"

To get both the index and the value:

for index in "${!array[@]}"
    echo "$index ${array[index]}"

Append element to array 🔗

Bash dates [bash][date]

All of these notes are about date from GNU coreutils on Linux. I believe some parameters are diferent on MacOS.

Everything in there is basically a rehash of man date.

Timestamp / Date conversions 🔗

date +"%s"  # Get current date as timestamp

alias ts2date='timestamp2date' # Parse timestamp as date
function timestamp2date {
    echo $(date -d @$1)
Bash loop command [bash][loop]

One liner to do loops

Don't forget there is no ; between do and the first command

while true; do ls -lh file; sleep 1; done
Docker Using a proxy [docker][proxy]

In order to pull images (from instruction or docker pull command) via the proxy:

  1. Create a systemd drop-in directory:

    mkdir /etc/systemd/system/docker.service.d

  2. Add proxy in /etc/systemd/system/docker.service.d/http-proxy.conf file:

    # /etc/systemd/system/docker.service.d/http-proxy.conf

  3. Flush changes:

    systemctl daemon-reload

  4. Restart Docker:

    systemctl restart docker

In order to have the apt-get working inside the Dockerfile via the proxy you have to add some build args to the command:

docker build --build-arg http_proxy= --build-arg https_proxy= .

Docker cheatsheet [docker]

docker exec reference

Run interactive shell on container

docker exec -it <container_id> bash

Run command on container

docker exec -d <container_id> touch /tmp/test

Set an environment variable in the current bash session.

docker exec -it -e VAR=1 <container_id> bash

Select working directory for the command to execute into

 docker exec -it -w /root <container_id> pwd
Docker move data directory [docker]

Instructions copied from this site

By default Docker stores its data in /var/lib/docker

To move this data:

  1. sudo service docker stop

  2. Add this to /etc/docker/daemon.json (file might not exist)

    "data-root": "/path/to/your/docker"

  3. sudo rsync -aP /var/lib/docker/ /path/to/your/docker

  4. sudo mv /var/lib/docker /var/lib/docker.old

  5. sudo service docker start

  6. Test

  7. sudo rm -rf /var/lib/docker.old

Dunst [dunst][dunstctl][notification]

The Arch wiki article says it all.

Test notification 🔗

With notify-send (works with all notification daemons):

notify-send 'Test notification'
notify-send -u low|normal|critical 'Notification with urgency'

With dunstify (dunst tool working only with dunst):

dunstify -h string:x-dunst-stack-tag:test Test -A 'tested,default'
dunstify -h string:x-dunst-stack-tag:test Testing

Enable tap to click in i3 WM [i3][touchpad]

Cody Craven made an excellent blogpost explaining very clearly how to enable tap to click on i3.

That worked perfectly on my Lenovo T490s with Ubuntu 21.10 and i3 4.20. The TL;DR is directly copied from Cody's post and I keep it here only because it will be easy for me to find it back.

The different available options are listed with [man libinput](#

sudo mkdir -p /etc/X11/xorg.conf.d
sudo tee <<'EOF' /etc/X11/xorg.conf.d/90-touchpad.conf 1> /dev/null

Section "InputClass"
    Identifier "touchpad"
    MatchIsTouchpad "on"
    Driver "libinput"
    Option "Tapping" "on"
    Option "NaturalScrolling" "on"
    Option "ScrollMethod" "twofinger"
    Option "TappingDrag" "on"
    Option "TappingDragLock" "on"
    Option "DisableWhileTyping" "on"
FFmpeg - Convert video to gif [ffmpeg][gif]

After recording a screen cast with SimpleScreenRecorder on Ubuntu I use the following ffmpeg command to convert them to gif to be used on this blog.

ffmpeg -i input_file.mkv -vf "fps=10" -loop 0 output_file.gif

The quality is not the best, at one point I should take the time to find out how to do it well. I reused the command from this SO answer.

Firefox shortcuts [firefox]

Built-in shortcuts 🔗

Move tab left/right (vimium)</>
Focus address bar<C-j>/<C-k>
Backwards/Forward navigation<A-Left>/<A-Right>

Vimium config 🔗

Custom key mappings

map l nextTab
map h previousTab
map d removeTab

Custom search engine 🔗

To use search engines site: filter automatically:

  • Create a bookmark with the the url and %s for the query string like this:
  • Add a keyword to the bookmark e.g. v
  • In the address bar search with v my query
Git commit fixes [git][commit]

This link is dope
(And someone made a better UI here)

TODO: Extract the ones I need but can never remember

Remove commit from history 🔗

Reminder on zsh escape ^ in HEAD^ with HEAD\^

Remove the last commit from history but keep the working tree

git reset HEAD^

Remove the last commit of the history completely and discard changes

git reset --hard HEAD^ # THIS DISCARDS CHANGES

Sign an older commit in your branch 🔗

This will do an interactive rebase, playing git commit --amend --no-edit -n -S
after each commit

(Check if -n is useful I can't find it in the man)

git rebase --exec 'git commit --amend --no-edit -n -S' -i my-branch

Change the date of a commit 🔗

Additional details in this SO answer

GIT_COMMITTER_DATE="Wed, 28 Jul 2021 08:12:19 +0200" GIT_AUTHOR_DATE="Wed, 28 Jul 2021 08:12:19 +0200" git commit

Date formats

Git internal format = <unix timestamp> <time zone offset>, e.g.  1112926393 +0200
                    <unix timestamp> is the number of seconds since the UNIX epoch.
                    <time zone offset> is a positive or negative offset from UTC. (E.g CEST is +0200)
RFC 2822            = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601            = e.g. 2005-04-07T22:13:13

Get the logs of a specific line 🔗

See this SO answer

git log -L '/the line from your file/,+1:path/to/your/file.txt'

or with line number:

git log -L15,+1:'path/to/your/file.txt'

or with a funcname:

git log -L :<funcname>:<file>

Auto fix commits 🔗

To fix an existing commit aaaaaa:

# Do changes
git commit --fixup aaaaaa
git rebase -i --autosquash master

-i --autosquash will open an interactive rebase but the fixup commits are already ready.

Grep [bash][grep]

Exclude multiple directories 🔗

grep --exclude-dir={node_modules,src}

Have grep colors in less 🔗

grep --color=always | less -r
Keyboard input speed on Linux [linux][keyboard][xset]

Make the delay between Key presses shorted on Linux

  • First parameter is the delay before the auto repeat starts
  • The second is the time between two auto repeats
xset r rate 150 50
Remap <alt>+hjkl to arrow keys on Linux [linux][keyboard][autokey]

One way to have alth, altj, altk, altl mapped to , , , is to use autokey.

⚠ Note that autokey is an X11 app that will not work with Wayland ⚠

On Ubuntu 21.04 one can install autokey from the repos with sudo apt install autokey-gtk.

In autokey one can create four different scripts with the following content:

# script arrow_left

# script arrow_right

# script arrow_up

# script arrow_down

Then on each script set a hotkey (The "Press to set" feature is useful to set combinations like alth):

Setting a hotkey

Scp [bash][scp]

Basically the same syntax as cp (i.e. scp [source] [dest])

# Local to remote
scp ./local/path user@remote-host:/home/user

# Remote to local
scp user@remote-host:/home/user ./local/path 

Useful options 🔗

-rCopy directories
-iProvide identity file
-PSpecify port
Screen [screen]

Basic usage 🔗

Start a new session with session namescreen -S <session_name>
List running sessions / screensscreen -ls
Attach to a running sessionscreen -x
Attach to a running session with namescreen -r <session_name>
Detach a running sessionscreen -d <session_name> or <C-a><C-d>
Search git commits [git][commit][search]

Find commits which change the number of occurences of a string 🔗

git log -SsearchedString

Find commits with a commit message including a string 🔗

git log --grep=searchedString

Shell redirections [bash][shell][output]

Redirect stdout and stderr to a file 🔗

command > /dev/null 2>&1
Systemctl & systemd cheatsheet [systemd][systemctl]

I always get confused in the syntax between systemctl and service commands. To be updated with the missing ones next time I one them.

List services 🔗

systemctl list-units
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=failed

Service status 🔗

systemctl status sshd

Service action 🔗

systemctl restart sshd
Tmux [tmux]

List sessions 🔗

tmux list-sessions

Attach session 🔗

tmux a -t [session-id]
Tmux list all 256 colors [tmux][colors]
for i in {0..255}; do
    printf "\x1b[38;5;${i}mcolour${i}\x1b[0m\n"
Xargs [bash][xargs]

Super useful opinionated guide to xargs

Examples 🔗

# Don't split input
echo "alice bob" | xargs echo hi
# hi alice bob

# Split input by whitespace and specify a number for each command
echo "alice bob" | xargs -n 1 echo hi
# hi alice
# hi bob

echo "alice bob oscar leon" | xargs -n 2 echo hi
# hi alice bob
# hi oscar leon

# Split input by new line
ls | egrep 'pack' | xargs -d $'\n' -- ls -l
# -rw-rw-r-- 1 afabre afabre   1286 août  21 21:05 package.json
# -rw-rw-r-- 1 afabre afabre 162685 août  21 21:05 package-lock.json

# Run in parallel with -P
xargs -P
Zsh completion functions [shell][zsh]

A quick trick to have custom completion on the aliases I create.

First create the function and the alias, they can be in ~/.bash_aliases or whatever.

myCoolFunction() {
    echo "Here are the args from my function $@"
alias mcf='myCoolFunction'

Then create the completion function (best practice underscore+function name) which can be anywhere too. An interesting list of the helpers provided by zsh for the completion functions is here.

# Suggest words as completion options
_myCoolFunction() {
    compadd "$@" foo bar baz

# Or have completion options with additional description
_myCoolFunction() {
    local -a options
        'arg1:To do something'
        'arg2:To do something else'
        'arg3:A different argument'
    _describe 'mcf' options

Finally in ~/.zshrc we can register _myCoolFunction as the completion function of myCoolFunction:

compdef _myCoolFunction myCoolFunction

Once everything is ready in a new shell typing mcf <TAB> should yield the 3 completions options.

If things don't work one can check the completion function for a particular function (It does not work with the alias) with:

echo $_comps[myCoolFunction]

and the implementation with

functions $_comps[myCoolFunction]

Finally I should check how to make it work with the defined files (~/.oh-my-zsh/completions) and understand why the compdef command only works when put in .zshrc.

Back to top