7 More Habits of Highly Effective Linux Users

This is a response to an article I read from , The 7 Habits of Highly Effective Linux Users. In it, he professes seven useful tips for new Linux users he wishes were impressed upon him when he began his adventures as a Linux user. Kudos to Rami, all his habits are not only highly effective but great user practices. This made me realize that we Linux users that bash Windoze all day have a responsibility for sharing more information like this; my apologies Rami, for not helping out sooner.

As a Linux user for about twelve years now, here are seven more habits I wish I was told about (and some I was!) when I was starting, and you may want to consider adopting yourself to become a savvy Linux user:

1. Never EVER Login as Root
Rami's number one habit is to never log in as user root. A worthy habit, Rami is now qualified to be a sys admin within a linux production environment. Although there are most definitely times you need to become the root user, get in the habit of using sudo to become root.

Sudo (pronounced soo-doo, not soo-doe) stands for "Super User Do", a.k.a., do as the super user. With it, you can limit certain commands to be run as the root user to specific user accounts.

Why? One, because you can keep an audit trail of who is doing what as the root user, and two, it helps you get in the habit of not logging in to the root account and staying there which can be disastrous if you execute certain commands and forget you're root.

How? To give yourself super easy sudo access, as the root user execute the command visudo and add your name in the configuration file (uses vi as the default editor on most systems):

myusername ALL = (ALL) NOPASSWD: ALL

The "NOPASSWD: ALL" will allow you to execute commands as root without having to enter the root, or your own password. Save the file and then to run a command as root, precede it with the sudo command:

# sudo /etc/init.d/mysql restart

If you need to get into a root shell, don't bother su-ing, use sudo to su instead:

# sudo su -

And you're good to go.

2. Always Backup Configuration Files You Edit!
There's nothing worse than updating a configuration file and then finding out the app no longer starts! What was that change you made? How do you go back?

Get in the habit of creating a hot backup before editing, even if it's quick and dirty:

# cp httpd.conf httpd.conf.o

I usually make a backup with the current date, so if I have multiples, I have a history:

# cp httpd.conf httpd.conf.04.20.2008

This will save you severe pain, TRUST me!

3. Use rm -r with care!
Ok,one of the biggest gags new linux users may get is to execute "rm -r /" to solve a problem. Har har... but I actually did something like that once. No, not per a suggestion to fix a problem, but because I was using rm in a dangerous way. What made it worse is I did it on a company production system many many years ago. The head unix admin set me straight.

When executing rm to remove a directory or files, it's best to either specify the full path or the directory itself instead of deleting locally. E.g.:

# /etc/foo> rm -r . <-- bad# /etc/foo> cd ..
# /etc> rm -r foo <-- good
# /> rm -r /etc/foo <-- even gooder-er

Some shells will not tell you exactly what directory you're in. If you happen to forget where you are, or just aren't paying attention, a rm -r . will wreak havoc, like it did for me; I was in the root directory when I did it while I thought I was somewhere else. I ended up making things real bad for someone else.

4. Move through directories quickly
On Windoze, I got used to moving in and out of directories in a monolithic way. To reduce the amount of typing you need to do in a shell to move around directories, get used to using the dot notation:

Longer Way:

# cd /var/log/mysql
# cd ..
# cd samba

Shorter Way:

# cd /var/log/mysql
# cd ../samba

The ".." notation simply means "move back one directory" where "." means current directory. Therefore, to get a directory listing of the current directory you'd do:

# ls -lh .

And to move around more quickly, you can use the .. notation:

# cd ../../../foo <-- moves you back three directories, if in a nested directory

After a little practice, you won't stop using this habit and you'll try to figure out how you lived without it.

5. Dump ftp; use scp
I cringe when I hear people still use ftp to move files. With ssh, you can securely move files across servers. On top of the security, the process is also far more simple, and pretty much as easy as using the cp command.

To move a file from the system "foo" to system "bar":

# scp this_file myusername@bar:/tmp
password: ******

In the above example, your moving the file "this_file" to the system "bar" inside the directory "/tmp". If you omit the "myusername@", it will use the username you're logged in as on your local host. If you omit the "/tmp" (keeping the ":"), it will default putting the file in your home directory on the remote system, "bar".

To copy whole directories, you can add the -r flag, like the cp command:

# scp -r /usr/local/apache bar:/usr/local

You can also copy a file from the remote host to your local one:

# scp bar:/tmp/this_file /tmp

If you're going to copy LOTS of files recursively, you may want to tar up the directory first and then scp it, this could literally speed up the transfer hundreds of times, reducing a copy that might take twenty minutes to a matter of seconds:

# tar zcvf /tmp/apache_tar.gz /usr/local/apache
# scp /tmp/apache_tar.gz bar:/tmp

6. Secure ALL your connections to remote servers, using secure tunnels
I used to be a hero at a particular company I worked at because I was able to get around the corporate web filter and browse any site, any time, and not get logged doing it. This is because I was running squid on my home server to act as a proxy and tunneling the squid port over ssh. If you're not quite following, I tricked my local system to direct web traffic through my secure connection, and not the companies.

This is a useful tactic to use if you have web services, or other services where you connect to a remote port that are behind a firewall. For example, let's say you're running webmin on a remote server. Instead of keeping port 10,000 open to the world, you can block it at the firewall and use ssh to trick port 10,000 on your local host to think it's port 10,000 on the host you're logged in to.

To do this, ssh into the remote host and use port redirection:

# ssh -L10000:localhost:10000 myuser@bar
password: ******

Once logged in, pu the address "http://localhost:10000" in your web browser and voila; you're now connected to your webmin session running on the remote host!

The first number after the -L specifies the port your local host will use to redirect traffic. Therefore, if you used -L5000:localhost:10000, your web address would look like this: http://localhost:5000. The traffic would go to port 10,000 on the remote host.

If you're sshing into a gateway of sorts and need to access a port on a server within the network of the gateway host, you can add the ip address where you specified "localhost" in the ssh command:

# ssh -L10000:192.168.1.10:10000 myuser@bar

Where 192.168.1.10 may be a host on the gateways network you want to connect to. Your web address to connect would be the same as in the first example, http://localhost:10000

You can do this with a variety of ports and services; experiment to find out which ones may work best.

7. Know Your Logs
The mark of an amateur user is one who runs into a problem and deletes files, changes configurations, uninstall/reinstalls... reboots, to resolve the issue. I am perplexed at the amount of users that don't check the log files of the applications to determine what's wrong. In most cases, the log files will tell you the exact error you're application is experiencing when running in to problems. I even catch myself not checking my logs first sometimes... shame on me.

The first useful log you should be aware of is the syslog messages file. Located in /var/log, you should check this file's contents first if you're not sure what log files to check if you see a problem. A useful way to read recent messages would be to execute a tail on it:

# tail -100 /var/log/messages

Most applications will either install with their own log files, or redirect their status messages to the syslog. In the cases where they have their own log files, you'll want to check them independently to resolve issues. Some examples of where you may find application log files.

These files may be located in different locations on different systems, even when dealing with the same application! For example, on a default ubuntu installation you may find apache's log files in /var/log/apache2. On my systems, because I build my apache, it's located where I install it, /usr/local/apache/logs. Further, I have multiple web servers and I have their log files going to different files and locations. For example, I may have one slice of my apache log going to /web/logs/access.log.

To determine where your application is logging it's information, you would need to look at its configuration file. Usually, the configuration file will specify if the log file is going to the default logger, syslog, which would dump into /var/log/messages on most systems, or it will show the file(s) where it dumps the log data.

It can sometimes also be useful to read the log files in real-time to diagnose a problem. How do you do this? Run the tail command with the -f flag to view messages coming into the file as they're written:

# tail -f /var/log/messages

This is one of the most useful ways to read log files and diagnose problems.

If you can't find hints of your problem in any of the log files, something system related could be happening. To check the system status, run the command "dmesg" to get a listing of system specific status messages:

# dmesg
...
...
end_request: I/O error, dev sdd, sector 1537831
scsi 5:0:0:0: rejecting I/O to dead device
scsi 5:0:0:0: rejecting I/O to dead device
scsi 5:0:0:0: rejecting I/O to dead device
scsi 5:0:0:0: rejecting I/O to dead device
scsi 5:0:0:0: [sdd] READ CAPACITY failed
scsi 5:0:0:0: [sdd] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK,SUGGEST_OK
scsi 5:0:0:0: [sdd] Sense not available.
scsi 5:0:0:0: rejecting I/O to dead device
scsi 5:0:0:0: [sdd] Write Protect is off
scsi 5:0:0:0: [sdd] Mode Sense: 00 00 00 00
scsi 5:0:0:0: [sdd] Assuming drive cache: write through
scsi 5:0:0:0: rejecting I/O to dead device
usb 1-5: new high speed USB device using ehci_hcd and address 5
usb 1-5: new device found, idVendor=19ff, idProduct=0305
usb 1-5: new device strings: Mfr=1, Product=2, SerialNumber=3
...
...

Keep in mind, this readout can get friggin huge and you may need to redirect the output to a file to read:

# dmesg > /tmp/dmesg_output

You can then open the file /tmp/dmesg_ouput to read the status. Note, this output will contain system messages since the system boot!