CRON Cheatsheet

I’m tired of always looking up CRON scheduling, so here it is including some examples.

CRON Scheduling table:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of week (0 - 6)
# │ │ │ │ │                                      
# │ │ │ │ │
# │ │ │ │ │
# * * * * *  command to execute

Note that the day of week (0-6) typically starts with Sunday as the first index (0), so Monday = 1, Tuesday = 2 and so on. On some systems you might be able to also use 7 as Sunday.

CRON Examples:

Note that all the cron jobs output are redirected to /tmp/log.txt. If omitted, the default is to send an email to the sysadmin email address (if configured).

Run Python script every night at 02 am

* 02 * * * python /path/to/ >> /tmp/log.txt 2>&1

Run PHP script once every two hours

0 */2 * * * php /path/to/script.php >> /tmp/log.txt 2>&1

Run shell script every 10 minutes

*/10 * * * * /path/to/ >> /tmp/log.txt 2>&1

Workaround for running a script every 15 seconds

* * * * * /path/to/ >> /tmp/log.txt 2>&1

* * * * * sleep 15; /path/to/ >> /tmp/log.txt 2>&1

* * * * * sleep 30; /path/to/ >> /tmp/log.txt 2>&1

* * * * * sleep 45; /path/to/ >> /tmp/log.txt 2>&1

Run a script every weekday at midnight

0 0 * * 1-5 /path/to/ >> /tmp/log.txt 2>&1

Run script every Monday in June, July and August at 0530

30 05 * 6-8 1 /path/to/ >> /tmp/log.txt 2>&1

Related post:

Linux Cheatsheet

List a rough overview for automated ssh login attacks

We all love to read log files, and for Linux I tend to simplify that search process if I know what I’m looking for. As you probably know many daemons and programs  logs to /var/log , but usually I don’t care to specify the file (like syslog or mysql.err etc) so I just do cat on all the files in the log dir.

So here’s a quick gem to list automated ssh attacks to your server:

$ sudo cat /var/log/* | grep BREAK-IN


Clean unused kernels when boot partition is full

My /boot partition keeps getting full so I must regularly clean it.

Quick instructions:

  • Show current linux kernel used
    uname -r
  • Show all installed kernels
    dpkg --list | grep linux-image
  • Remove old kernels which are no longer in use
    sudo apt-get remove linux-image-xxxx
    (replace xxxx) with the unused version numbers
  • For good measure, clean unused packages
    sudo apt-get autoremove
  • Optional: if the GRUB boot list is full of old kernel entries, update it by running
    sudo update-grub

Check out these articles for more info:

Install SMTP client on Ubuntu server

  1. Install the light-weight SMTP client “ssmtp”
    sudo apt-get update && sudo apt-get install ssmtp

  2. Configure ssmtp (sudo nano /etc/ssmtp/ssmtp.conf) [1] and set correct info for the following lines:
    1. root=
    2. mailhub=
    3. AuthUser=
    4. AuthPass=
    5. hostname=
    6. rewriteDomain=

  3. Make aliases for the local user to correct email address [2]
    sudo nano /etc/ssmtp/revaliases

  4. ssmtp uses the local users Full name from the OS as the email sender, so make sure your name is correct. Change by using command
    sudo chfn -f "John Doe" yourUser

  5. Verify ssmtp works by sending a test mail with command [3]


[1]: Example config

# Config file for sSMTP sendmail
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named


# Where will the mail seem to come from?

# The full hostname

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address


[2]: Example aliases

# sSMTP aliases
# Format: local_account:outgoing_address:mailhub
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
# where [:port] is an optional port number that defaults to 25.


[3]: Example ssmtp test

Subject: Testing ssmtp
enter your body text here
via SMTP server.


Linux Cheatsheet

Print lines of code (amount) for all .php files in current directory

find . -name '*.php' | xargs wc -l

Show all group memberships for current user


Get username for Apache service

ps aux | grep apache

(Relatively) secure permissions on public html folder for Apache/nginx

The goal is to set root as file owner and add the www-data as group (www-data is the group of the user running apache/nginx). Then, for every user which requires write-permission, simply add them to the www-data group.

sudo chown root:www-data /path/to/htdocs/* -R 
sudo chmod 775 /path/to/htdocs/* -R
chmod 775 gives everyone R/W/X except public because they shouldn’t have write permissions

Change www-data with whatever group belonging to the user account which is running apache/nginx.

Create an alias for bash commands and/or custom functions

First you need to open your bash profile config file. If preferred, you can use nano and open it with: nano ~/.bashrc

Example: Add a shorthand command for ls and tail with some extra parameters:

alias l="ls -lahS"
alias t='tail -n 200 $1'

As you can see, the tail command also reads file argument given to the command.

Example: Add a custom function for searching for a string in all files in current directory:

grepfor() {
grep -rnw './' -e "$1"

When done, reload your config file by running:
. ~/.bashrc

Search for string in files

grep -rnw '/path/to/dir/' -e 'stringpattern'

List only files with size above 100 MB

find . -type f -size +100M -exec ls -lh {} \;

This command scans the current dir for files above 100 MB and then executes the ls -lh command for those files. You could also say -size -10M to do the same for files below 10 MB in size.

Clean/format USB drives

sudo fdisk -l
sudo mkdosfs /dev/xxx # (i.e sdb1)
sudo mkdir /media/usb
sudo mount /dev/xxx /media/usb

See uptime and average load


Change timezone

sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/Europe/Oslo /etc/localtime

Replace Europe/Oslo with your preferred timezone

Remove password for local user (make it passwordless)

sudo passwd --delete username

See current users logged on server

users (usernames only)


who(includes extra information like logon time and IP address etc)

Show IP addresses for all local network cards (including local loopback)

ifconfig | grep inet | cut -d: -f2 | cut -d" " -f1


ifconfig | grep 'inet addr' | cut -d: -f2 | awk '{print $1}'

If you wish to see the IP address for a specific NIC (network interface card), simply append the name after ifconfig, like ifconfig eth0 | ...

Map network share

$ sudo mkdir /mnt/ShareName
$ sudo mount -t cifs -o username=domain\username,password=pw //server/share /mnt/ShareName

List automated ssh attacks to your server from syslog:

$ sudo cat /var/log/* | grep BREAK-IN

This post will be continually updated with useful commands and other notes for Linux environments

Related posts:

Delete entry from Bash history

First type history to see your bash command history.

Find the entry/command you’d like to erase from history and note the id on the left column.

history -d 1234

Replace 1234 with the actual ID.


$ history
  640  cd ~
  641  ls -la
  642  crontab -e
  643  exit
  644  free -h
  645  df -h
$ history -d 645
$ history
  640  cd ~
  641  ls -la
  642  crontab -e
  643  exit
  644  free -h

As you can see, the df -h command was erased from the history.

Add remote access to MySQL server

Follow the commands below to setup a new user and open up for remote access to a specific database on your MySQL server.

$ mysql -u root -p
Enter your MySQL root password.
mysql> CREATE USER 'itdb_admin';
mysql> CREATE DATABASE itdb_db;
mysql> GRANT ALL PRIVILEGES ON itdb_db.* to 'itdb_admin'@'%' IDENTIFIED BY 'my-password' WITH GRANT OPTION;
mysql> EXIT;
$ sudo nano /etc/mysql/my.cnf
Comment the following line by setting a # in front (to disable it):
bind-address =
$ sudo service mysql restart

Quick summary:

1) Open the MySQL CLI
2) Create a new database
3) Create a new user
4) Give the user full access to the database. Notice the '%' which means we’re talking about remote access. The same user can have different access levels based on the connection (whether it’s remote or local)
5) Flush/refresh the privileges so they become active
6) Disable bind-address so the MySQL server will listen on any source address
7) Restart the MySQL service to reload the config file

Setup reverse SSH tunnel

Here’s a quick example for setting up reverse SSH tunnels on clients which can be controlled via the server from anywhere. This example presumes all the client computers has some sort of unique ID/hostname, like 9001, 9002, 9003, 9004 etc. Let’s say we have 10 clients stuck behind a firewall we’d like to access.

Start the SSH server on all clients like this:

ssh -R 1xxxx:localhost:22 // replace xxxx with this client's unique id

Now we have all our clients setup with a reversed ssh tunnel.
If we’d like to ssh into id 9003 we run the following command from the server:

ssh user@localhost -p 19003

Lets ssh into 9005 instead:

ssh user@localhost -p 19005

Replace user with a local user on the client machine.


I want to ssh into my Raspberry Pi. Local username is pi.

  • Step 1 – setup reverse ssh tunnel on the raspberry:
    ssh -R 19999:localhost:22
  • Step 2 – from my “” server I run the following command:
    ssh pi@localhost -p 19999

Combining with sshpass and autossh

sshpass -p "mypassword" autossh -R 19999:localhost:22