Troubleshooters.Com and T.C Linux Library Present

Linux Quick Hacks

Copyright (C) 2000-2013 by Steve Litt, All rights reserved. Material provided as-is, use at your own risk. 


Ascii Character Lister

To list printable characters and their ascii values, do the following:

perl -e 'foreach $x (32..126){print "_" . chr($x) . "  " . $x . "\n"}'

To find the ascii code for a specific character (other than the space character, use $ in this example), do this:

perl -e 'foreach $x (32..126){print "_" . chr($x) . "  " . $x . "\n"}' | grep '_\$'

Normal characters don't need and can't use the backslash, so to find the asci value of lower case 'd' you'd do this:

perl -e 'foreach $x (32..126){print "_" . chr($x) . "  " . $x . "\n"}' | grep '_d'

To find the character corresponding to an ascii value, do this (example uses 100 as the ascii value):

perl -e 'foreach $x (32..126){print "_" . chr($x) . "  " . $x . "\n"}' | grep ' 100'

Man pages formatted as text

Man pages look great on console screens, but piped to files or to browsers they quickly degenerate into cluttered conglomerations of reverse linefeeds and backspaces designed to simulate "bold" on your console screen. You get rid of the clutter by piping the output of man through thecol command. With no args, col blows off the reverse linefeeds but leaves the backspaces (^H). The command you want (using the ls man page as an example) is:

man ls | col -bx > myfile.txt

The preceding command writes the man page to myfile.txt, without backspaces (the -b) and with spaces substituted for tabs (-x).

Man pages formatted as html

Here's a CGI script that uses a command similar to that discussed in the preceding section to output a man page to a browser. I call it mann.cgi:

#!/usr/bin/perl -w


use strict;


sub GetData()
  if($line =~ m/Tman=(.*)&Bsub/)
    $cmd = $1;
  elsif($line =~ m/Tman=(.*)$/)
    $cmd = $1;
    $cmd = "InternalError";

sub MakePageTop()
  print "Content-type: text/html\n\n";
  print "<html><head><title>Man Page Displayer</title></head><body>\n";

  print "<center><big><big><big><strong>\n";
  print "Man Page Displayer<p>\n";
  print "</strong></big></big></big></center>\n";

sub MakeForm()
  print "<FORM ACTION=\"./mann.cgi\" METHOD=\"POST\">\n";
  print "<b>Command to look up:\n";
  print "<input type=\"text\" name=\"Tman\" size=\"24\"";
  print " value=\"$cmd\"></b>\n";
  print "<INPUT type=\"submit\" name=\"Bsub\" value=\"Submit\">\n";
  print "</form>"; 

sub MakeManPage()
  print "<pre><b>";
  print `man $cmd -a | col -bx`;
  print "\n</b></pre>";

sub MakePageBottom()
  print "</body></html>\n"; 

sub main()


Shellscript File Tests

Here's a script to test for a file's existence:

if [ -e $file ]; then
 ./myUtil $file
[ -b $file ] True if file exists and is block special.
[ -c $file ] True if file exists and is character special.
[ -d $file ] True if file exists and is a directory.
[ -e $file ] True if file exists.
[ -f $file ] True if file exists and is a regular file.
[ -g $file ] True if file exists and is set-group-id.
[ -k $file ] True if file has its ``sticky'' bit set.
[ -L $file ] True if file exists and is a symbolic link.
[ -p $file ] True if file exists and is a named pipe.
[ -r $file ] True if file exists and is readable.
[ -s $file ] True if file exists and has a size greater than zero.
[ -S $file ] True if file exists and is a socket.
[ -t $fd  ] True if fd is opened on a terminal.
[ -u $file ] True if file exists and its set-user-id bit is set.
[ -w $file ] True if file exists and is writable.
[ -x $file ] True if file exists and is executable.
[ -O $file ] True if file exists and is owned by the effective user id.
[ -G $file ] True if file exists and is owned by the effective group id.

Directory Size Lister/Sorter

Have you ever wondered which directories and trees take up all the diskspace? Questions like this come during pruning/archiving, backup, and numerous other activities. Make the following oneliner script (I call it dirsizes) to find out:

du -sm $(find $1 -type d -maxdepth 1 -xdev) | sort -g

The preceding shellscript prints every directory below the one called as an argument, together with its size, sorted with the largest at the bottom. We sort largest at bottom so there's no necessity to pipe it toless. Instead, you can see the largest 24 on the screen after the command.

If you find a large tree, but can't delete the whole thing, you can explore just that tree by using its directory as the argument, and you'll see all its subtrees and how much space they take.

But let's say you want to see ALL directories in the tree, instantly zeroing in on big diskspace directories. Make the following shellscript, which I call alldirsizes:

find $1 -type d  | xargs du -sm | sort -g

Both these scripts do more than just add filesizes. They take into account inodes, so they reveal the space that would be recovered if the directories were deleted.

Both of these scripts are most accurate when run as root, but they're pretty informative run as just a normal user.


X-Sender: slitt@
X-Mailer: QUALCOMM Windows Eudora Light Version 3.0.6 (32)
Date: Fri, 24 Nov 2000 11:59:15 -0500
From: Steve Litt <Steve Litt's email address>
Subject: [LeapList] Cups tips
X-Mailman-Version: 1.0rc2
List-Id: General Linux Discussion List for LEAP <>

On my mandrake 72 I noticed that using lpr to print a text file was
printing too close to the left and cutting off half the first character.
This is a cups system.

So I looked at http://localhost:631, which is the cups equivalent of swat.
It pointed me to a cups manual, which noted that the lpr command can be
used to change margins:

lpr -o page-left=24 /etc/smb.conf

The preceding prints smb.conf with a left margin of 1/3 inch (24/72). There
are a smorgasbord of options for duplexing, characters per inch, page
ranges (and isn't that nice when a .ps or .pcl file jams in the middle),
and tons of other stuff. However, I couldn't make the brightness setting
work right, as when I made the text darker, the background on the last page
turned dark.

By the way, I'm sure there's some place where I can make the page-left
default 24 points, but I just haven't found it yet.


Mouse: Fast and Accurate Mousing Under Linux

By default, the mouse under Linux is typically much too slow, requiring large hand movements to move the pointer. This is inconvenient, and although I'm a layman with regard to ergonomics, I personally fear those large hand movements put me at greater risk for repetative motion injuries. Luckily, this problem is easy to fix.

Many people think the fix is to boost the acceleration. That makes the mouse fast enough, but requires you to move the mouse quickly to traverse large distances, then slowly to zero in on the exact target. With an overly large (like 5) acceleration, mousing resembles golf -- one or two drives followed by a couple of putts. Not good for productivity.

The problem isn't acceleration. The problem is that the pointer moves too few pixels per inch of mouse travel. You should be able to move a good 600 pixels per inch of mouse travel, not the ~200 provided by a default Linux box. The solution is to add a resolution option to the pointer section of /etc/XFConfig86-4 file, as shown below:

# **************************************************
# Pointer section
# **************************************************
Section "InputDevice"

    Identifier "Mouse1"
    Driver      "mouse"
    Option "Protocol"    "imps/2"
    Option "ZAxisMapping" "4 5"
    Option "Device"      "/dev/psaux"
    Option "Emulate3Timeout"    "50"
    Option "Resolution" "1600"

# ChordMiddle is an option for some 3-button Logitech mice

#    Option "ChordMiddle"


You'll notice I use 1600 for the resolution. That's above the maximum, so it produces the maximum resolution. The preceding is for my Logitech optical mouse, but the Option "Resolution" "1600" line is appropriate for pretty much any mouse, although it's conceivable that for some mice you might want to go higher or lower than 1600.

After making the preceding addition, you must restart X to see the result.

Once you've upped the resolution, you can tweak the accelleration. Once I've fixed the resolution, I like an acceleration value of 2. Here's the command to get it:

xset m 2 1

To get a 3 to 1 acceleration, use this:

xset m 3 1

To make your mousing experience even better, use a teflon covered mouse pad. It's well worth the extra money.

Although technically trivial, the human-mouse interaction plays a major role in the perceived quality of the computer experience. Don't shortchange yourself. Tweak your mouse to your liking.

Recording, Playing and Converting sounds

First, make sure aumix is installed, and use it to set both the record and play volumes, and make sure the microphone is the record device and not muted. Don't use a GUI mixer -- they sometimes get it wrong.

To record a song from the microphone, just do this:

$ rec

If you want to change the volume, use -v, which is a float where >1.0 amplifies, and <1.0 attenuates. Note our hearing is logrithmic.

$ rec -v2

To play it back, do this:

$ play

To convert it to a .wav, do this:

$ sox mysong.wav

Sox can also amplify, flanger, phaser, echo, and various other effects. See man sox.

Finding Who Has a File Open

How often do mounts and umounts fail because you can't determine what is using the device? How many times can you not eject a CD because something's got it open? How many times have you experienced a "file browser" that keeps a directory open even after you've navigated out of that directory and clicked the "refresh" button? Who's got this thing open??? Use the fuser program to find out:

[slitt@mydesk slitt]$ /sbin/fuser -mu /d
/d:                   1693(slitt)  1891c(slitt)  1894  1894c(slitt)
  1907  1907c(slitt)  1908  1908c(slitt)  1909  1909c(slitt)
  1910  1910c(slitt)  1912  1912c(slitt)  1913  1913c(slitt)
[slitt@mydesk slitt]$

The preceding command is great for finding who is holding open mounted devices. But sometimes you want to find who is holding open plain devices: For instance, when you want to restart ALSA and can't because something's using it. Do this:

slitt@mydesk:~$ fuser -au /dev/snd/controlC0 
/dev/snd/controlC0:  22596(slitt)
fuser -au /dev/snd/

You get the owner and the process ID. From there you can research using ps ax.

Be sure to look at the fuser man page for details on other info you can obtain. You can even kill all processes accessing a file, though I highly recommend against such a heavy handed move.

Modem Init Strings

Delay for Voicemail Phones

On some phone systems with voicemail, when there are unheard messages, the dialtone beeps several times. This can prevent the modem from connecting. If you have this problem, you can solve it with a simple modem init string addition.

On a Hayes compatible modem, and the following string onto the end of your modem init string:


Register S6 determines the delay before checking for dialtone. By instituting a 4 second delay, by the time you check for a dialtone all the beeps will be gone. If 4 seconds isn't enough, try 10, and then trim it down from there.

The Modem Speaker

The following codes influence the modem speaker:

Modem speaker always off
Modem speaker on during dial and handshake
Modem speaker on always
Modem speaker on during handshake
L codes, if present, should follow M codes
Modem speaker soft
Modem speaker moderate
Modem speaker loud

How to enable X across a network connection

  1. You might need to institute the ssh connection as ssh -x <remote_ip>
  2. export DISPLAY="<local_ip>:0"
  3. ;xhost +<remote_ip>

Enabling Root on Ubuntu

If you're reading this now, you probably got a rude awakening when you tried to log into a Ubuntu box as user root. By default, it can't be done.

The trick is that Ubuntu enables anything, absolutely anything, via the sudo command. As a matter of fact, anyone logged in as any user can get a root shell with the sudo bash command. This in itself is a horrible security problem, because anyone who logs in, locally or remotely, as any user can have the way with the machine. This situation must be rectified immediately.

What you'll want to do, in plain English, is this:

  1. Get into a root shell
  2. Use the passwd command to enable logging into user root
  3. Test that you can log into root
  4. Disable overly permissive sudo capabilities

Here are the specific commands:

  1. sudo bash
  2. passwd root
  3. Ctrl+Alt+F3 to access a new CLI terminal
  4. Log in as root
  5. visudo

Turning Off OpenOffice Autocompletion

Of all the obnoxious "features" ever created, OpenOffice's "Word Autocompletion" is probably the worst. It makes the old "Microsoft Bob" look positively benign.

OpenOffice's autocompletion looks at your typing, and when a word appears to resemble another word in the document (or maybe elsewhere -- I'm not sure), it "helps" you by highlighting the whole word and adding letters to make it the resembled word. For a fast touch typist, it's distracting as the dickens.

So turn it off. From the OpenOffice menu, Tools->Autocorrect, and then uncheck the "Enable Word Completion" checkbox. That's it -- no more obnoxious word completion.

Copying Via SSH

If you want to copy an entire tree from one computer to another, sftp won't do it. Rsync can do it, but in certain cases rsync can consume too much RAM.  Assuming you're user slitt on the destination, and the tree belongs to user slitt on the source, here's a very easy to remember way to do it:

ssh slitt@source 'tar -cz /home/slitt/mytree' | tar -xzp

The p on the end of the extraction tar means "preserve permissions". The preceding places the home/slitt/mytree into the current directory, so you'll need to move mytree where you need it and delete the rest of the tree. To avoid that hassle and put mytree right into the current directory, use the -C option:

ssh slitt@source 'tar -C /home/slitt -cz mytree' | tar -xzp

Notice that everything within the singlequotes is performed on the remote computer, and everything after the last quote is performed on the local computer. The ssh program, when running a command, outputs the remote command's stdout on the local computer, so that data can be piped to local processes, which is what we're doing here.

The plot thickens if some files within the tar have different owners. In that case, the best thing to do is log into the local machine as root, go to the destination directory, and run it with the --same-owner argument on the extraction tar:

ssh slitt@source 'tar -C /home/slitt -cz mytree' | tar -xzp --same-owner

In my opinion, unless space is too tight to maintain both the .tgz and the extracted tree on the destination computer, this is better done as a three stage process:

ssh slitt@source 'tar -C /home/slitt -cz mytree' > /spare_directory/mytree.tgz
tar -tzp --same-owner -f /spare_directory/mytree.tgz
tar -xzp --same-owner -f /spare_directory/mytree.tgz

The first command creates a tarball, on the local computer, from the tree on the remote computer. The second command checks what's in the tarball, so if there's something wrong you can quit rather than possibly overwriting something valuable. The third command extracts the tarball to the current directory. Once again, the only real disadvantage of this is that you must have room for both the tarball and the extracted tree.

Running Terminals With Specific Fonts

This works for xterm and rxvt, and probably works for others. To specify a normal font (as opposed to a font used for bold), you run xterm with the -fn option:

rxvt -fn font_alias

The only trouble is, how do you find the font alias? That's contained in a file called fonts.alias. You find that file with locate command:

locate fonts.alias

When you look inside that file, each line has an alias followed by a space followed by a complete file specification, as shown in the following example from my computer:

lucidasanstypewriter-12 -b&h-lucidatypewriter-medium-r-normal-sans-12-120-75-75-m-70-iso8859-1

So in the preceding, the alias is lucidasanstypewriter-12. So your rxvt command would be as follows for this font:

rxvt -fn lucidasanstypewriter-12

Initiating svscan in Ubuntu (for djbdns, for instance)

The way DJB conceived djbdns, it would autostart using a line in /etc/inittab. Trouble is, Ubuntu doesn't use /etc/inittab. Instead, Ubuntu uses directory /etc/event.d by processing every file in it. So you create /etc/event.d/svscan with the following contents:

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
exec /command/svscanboot

Be very, very careful to get the right directory for the svscanboot command or it will silently fail and give you all sorts of trouble.

Telnetting to an SMTP Server

The following is an example of plain text username and password on port 26. The base64 is in plain text, and is easily converted back to the exact username and password. Note that at the end it bombs with an administrative prohibition, but it authenticated just fine.

This is how you test a username and password, and port number. First use perl to get your base64 username and password so you can paste them into prompts:

slitt@mydesk:~$ perl -MMIME::Base64 -e 'print encode_base64("myname\")'
slitt@mydesk:~$ perl -MMIME::Base64 -e 'print encode_base64("mypassword")'     

I'm going to use on port 26 as per the webhost.

slitt@mydesk:~$ telnet 26
Connected to
Escape character is '^]'. ESMTP Exim 4.76 #1 Wed, 11 Jan 2012 03:10:32 -0700
220-We do not authorize the use of this system to transport unsolicited,
220 and/or bulk e-mail.
ehlo Hello  []
250-STARTTLS 250 HELP auth login 334 VXNlcm5hbWU6 bXluYW1lQG15ZG9tYWluLmNvbQ== 334 UGFzc3dvcmQ6
bXlwYXNzd29yZA== 235 Authentication succeeded
mail from: 250 OK
rcpt to: 250 Accepted data 354 Enter message, ending with "." on a line by itself Here I stand. . 550 Administrative prohibition

Xchat: Globally Getting Rid of Join/Part messages

The following irc command gets rid of Join/Part messages on all channels, relieving you of the need to set it on each channel tab:

/set irc_conf_mode 1

This can be put in $HOME/.xchat2/xchat.conf:

irc_conf_mode = 1
There's probably already a value for irc_conf_mode in the config file, so be sure to find it and change its value -- don't put in a second key.

Finding All Info About All Partitions

Here's how you find out everything you need to know about every partition: Device name, uuid, label, and mount point (if any):


Do that command, and you'll know everything about every partition.

Linux Time Administration

Run this command:

sudo time-admin

You'll be presented with a dialog box with a timezone button for picking your timezone from a map with a list, and a Configuration dropdown enabling you to choose between "Keep syncronized with Internet servers" and "manual". If you pick "manual", you'll be presented with a calendar and hour, minute and second adjusters.


I know this time admin method works in Ubuntu 12.10. I don't know how widespread it is in the Linux world.

Single Tree Installation of Python Programs

Single tree installations are trivial to install: Just a recursive copy. Trivial to back up for the same reason. Trivial to transfer to another computer for the same reason. Few dependencies, easy deployment on a wide variety of platforms.

The challenge is that the program can be called from anywhere in on the computer, but it must "know" its anchor directory. Assuming the executable is in the anchor directory and not below it, this is pretty easy, simply by assigning variable targetdir to the value of arg0, doing the proper stuff so it always ends with exactly one slash. Once you have the anchordir directory, you can have your way with the whole tree by appending directories as necessary to locate all components within the tree. Here's how to do it in Python:

#!/usr/bin/python import sys import re import os anchordir = re.sub('/[^/]*$', '/', sys.argv[0]) if anchordir == './': anchordir = re.sub('/*$', '/', os.getcwd() + '/') datadir = anchordir + 'data/' templatedir = anchordir + 'templates/' print('Heres anchordir : {}'.format(anchordir)) print('Heres arg0 : {}'.format(sys.argv[0])) print('Heres datadir : {}'.format(datadir)) print('Heres templatedir : {}'.format(templatedir)) print('Armed with anchordir, you can have your way with the whole tree.')

Cooler still, this technique works even if the python file isn't permissioned executable, and instead is invoked like this:

python /home/slitt/myprograms/myapp/

Using the find Command, -mtime and -exec

If you're like me, the xargs command spooks you to no end. xargs is unpredictable and often dangerous unless you know it intimately.

The good news is, for all those times you were tempted to pipe find into xargs, you can use the find command's -exec option to do about the same thing. But you need to know the syntax:

find -type d -exec ls -ldF {} +

The preceding command finds all directories in the tree (-type d), and pipes them into an ls commands that doesn't recurse. Here's the explanation:

You can also use the find command to find files of a certain age. Files have three different times associated with them:

The only use I can think of for access time is criminal forensics. And even then, many filesystems are mounted noatime, removing access time as a useful measure. Access time is represented by -atime in the find command.

Creation sets both the creation time (-ctime) and the modification time (-mtime). In practice, I've had little success using -ctime in the find command, so I won't discuss it further.

Modification time is updated when a file is first created, and every time it's modified. I've found -mtime to be reliable, reproducible, and useful. It's March 28 today. Let's say I'm looking for a file I created in February. I might do something like this:

find -type f -mtime +25 -mtime -62  -exec ls -l {} + |  less

The reason I widened the margins on both the younger and older ends is I didn't take the time to get it exact. I'd rather see a few extraneous entries than spend a lot of time remembering the exact meaning of the plus and minus, which can be varied by certain other command options. If you really must have it exact, you'll need a lot more reading of the find man page, some experimentation, and know what to do with fractional days.

Back to Troubleshooters.Com * Back to Linux Library