Bash One-Liner

Bash One-Liner

Here some quick remember (for me and maybe for you) of some bash one-liner syntax. In fact, I use daily some « for loop » one-liners but I regularly forget how to include an « if statement ».

Bash One-Liner : syntax

For loop one-liner is the idea to use a for loop in a one line context.
In a script or program you will write it on multiple lines as follow :

for i in {1..10}
do
    echo ${i}
done

Pretty annoying for simple action… There we are, for loop (among others) can be written as a one-liner command.

for i in {1..10} ; do echo ${i} ; done

Here some exemple

me@laptop:~$ for i in {1..100} ; do touch File-${i} ; done
me@laptop:~$ for i in $( ls File-* | head -n 50 ) ; do echo "Not empty anymore" >> $i ; done

And What if I want to test some conditions and do something if my statement is true ?

me@laptop:~$ for i in File-* ; do if [ -s ${i} ] ; then echo "is empty !" > ${i}.emptyFlag ; else echo $i "is not empty" ; fi ; done
me@laptop:~$ for i in File-* ; do if [ -e ${i}.emptyFlag ] ; then rm $i ${i}.emptyFlag ; else :  ; fi ; done

Bash One-Liner : example

Here some examples in a more detail and in a reproductive manner. Let’s start a scratch directory :

me@laptop:~$ mkdir sandbox-OneLiner
me@laptop:~$ cd sandbox-OneLiner
me@laptop:~/sandbox-OneLiner$ pwd
/home/me/sandbox-OneLiner

Let’s create a bunch of test file:

me@laptop:~/sandbox-OneLiner$ for i in {1..100} ; do touch File-${i} ; done

Let’s check a bit what we create it :

me@laptop:~/sandbox-OneLiner$ ls File-* | head -n 2
EmptyFile-1
EmptyFile-10

If you want to sort you result numerically, you can pass the list to sort and ask him to use the second column of the string (-k 2). String will be cut using the ‘-‘ character (-t -).

me@laptop:~/sandbox-OneLiner$ ls File-* | sort -t - -k 2 -g | head -n 2
EmptyFile-1
EmptyFile-2

Let’s check how many file do we have :

me@laptop:~/sandbox-OneLiner$ ls File-* | wc -l
100

Now, we will add some content at half of the files. And in a same time put a flag on the empty one (just by creating a new file with an explicit extension). Then we will remove every files who posses the flag.

me@laptop:~/sandbox-OneLiner$ for i in $( ls File-* | head -n 50 ) ; do echo "Not empty anymore" >> $i ; done
me@laptop:~/sandbox-OneLiner$ for i in File-* ; do if [ -s ${i} ] ; then echo "is empty !" > ${i}.emptyFlag ; else echo $i "is not empty" ; fi ; done
me@laptop:~/sandbox-OneLiner$ for i in File-* ; do if [ -e ${i}.emptyFlag ] ; then rm $i ${i}.emptyFlag ; else :  ; fi ; done
me@laptop:~/sandbox-OneLiner$ ls File-* | wc -l
50

Ok there is a quick way to do it (and many more to just remove empty files) :

# starting by removing all the files :
me@laptop:~/sandbox-OneLiner$ rm File-*
me@laptop:~/sandbox-OneLiner$ for i in {1..100} ; do if [[ $i < 51 ]] ; then touch File-${i} ; else echo "Not empty" > File-${i} ; fi ; done
me@laptop:~/sandbox-OneLiner$ for i in File-* ; do if [ -s ${i} ] ; then rm $i ; else : ; fi ; done

For the specific task of deleting empty file there is the find command

me@laptop:~/sandbox-OneLiner$ rm File-*
me@laptop:~/sandbox-OneLiner$ for i in {1..100} ; do if [[ $i < 51 ]] ; then touch File-${i} ; 
me@laptop:~/sandbox-OneLiner$ find . -size 0 -delete

Some useful link :
http://www.bashoneliners.com/

Simple SSH config file and rsa keys to manage multiple remote server connections

SSH config file and RSA keys

I’m a biologist… and computer should remain simple because most of my time is spent behind a keybord, over network, working with several remote server. At the beginning, it was quite confusing to remember every couple of login@IpAdress as well as spicy passwords. But Open-Source community helped me to gain efficiency, providing me good advices and saving a lot of my time.
This post is about ssh configuration between your laptop and a remote server (both running under GNU/linux distros).

SSH config file

Since I discovered the ~/.ssh/config file, my work became easier : it works exactly like an alias.
You can type ssh Alias to connect directly on the right remote server (remote-serverA). Amazing, isn’t it ?

me@laptop:~$ nano .ssh/config
Host Alias
    HostName remote-serverA
    User login
    Port 22
    ForwardX11 yes

Instead of typing « ssh login@remote-serverA -p 22« , you just have to type « ssh Alias« , followed by your password.

RSA keys

The second very useful things is a complementary trick, the rsa key. Briefly, it consist of a private key (stored on your laptop for the example) and a public key (stored on a remote server). When initiating the ssh connection, the remote server will send a random message to your laptop, waiting the same message returned encrypted by your private key. If the return-message while decrypted by the public key, corresponds to the initial random message, the ssh connection is allowed (without any password !!!) Nice, right ?
So you need to generate a private and a public keys for identifying the two machines.
On your laptop and give them to each machine (I’m using Debian jessie) just type :

me@laptop:~$ cd ~/.ssh/
me@laptop:~/.ssh$ ssh-keygen -t rsa -b 4096 -f remote-serverA

You will be asked for passphrase, you can let it empty. If not, you will have to type you passphrase during each connection (instead of your password… which is initialy what we want avoid).
In you ~/.ssh/ directory, you should see

me@laptop:~/.ssh$ ls
config remote-serverA remote-serverA.pub

You should copy the content on the remote server in a file named ~/.ssh/authorized_keys. There is two possibility,

do it manually :

First print using cat to conserve the one-line structure. More will split the string, adding newline character (« \n ») to fit the size of your screen.

me@laptop:~/.ssh$ cat remote-serverA.pub

It should look

AAZcjdE45jhf[long character string]SHFJJ45djkSFF== login@laptop

Copy it in your clipboard or whereever you want and open an ssh connection to the remote-serverA :

me@laptop:~/.ssh$ ssh login@remote-serverA -p 22 [enter your password] Welcome on Server A :) 
login@remote-serverA:~$ 

Edit the « authorized_keys » file :

login@remote-serverA:~$ nano ~/.ssh/authorized_keys

Careful : the content of your key should remain on one line !!!

the lazy way:

All this step can be done in a one-ligner syntax by adding the content of the public key directly on the « authorized_keys » file using the pipe symbol (« | »), all of this encapsulated by an ssh connection.

me@laptop:~$ cat ~/.ssh/remote-serverA.pub | ssh login@remote-serverA "cat - >> .ssh/authorized_keys"

It should work !

Just try it, and feel you free to ask, comment or correct me :

me@laptop:~$ ssh Alias
Welcome on Server A !
login@remote-serverA:~$

Ressources :

https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
https://www.cyberciti.biz/faq/linux-generating-rsa-keys/