Linux Tips and Tricks

Apps

Opera - turning off the annoying tray icon

Opera 9 by default starts up by placing an annoying, pretty much useless icon in your system tray. To stop it from doing this, add the option "-notrayicon" to the script starting it up. This file is usually found in
/usr/bin/opera
and change the last line of this file to
exec "${OPERA_BINARYDIR}opera" "$@" -notrayicon



Thunderbird - changing default browser used to open links in e-mail

Edit or create the file
/home/USER_NAME/.mozilla-thunderbird/XXX.default/user.js
(USER_NAME in this path will be your user name, XXX will be random letters and numbers). The following example shows how to change the browser to Mozilla Firefox (i.e. if it was set to something else like Konqueror) and assumes the executable for Firefox is on the path and can be run by the command "mozilla-firefox", this can be replaced by the executable for other browsers if required. Add the following to the bottom of the "user.js" file making sure that when you do this both Firefox and Thunderbird are closed:
	user_pref("network.protocol-handler.app.http","mozilla-firefox");
	user_pref("network.protocol-handler.app.https","mozilla-firefox");
	
Development

Setting up a (secure) CVS server [cvs, ssh, linux]

  1. Download and install CVS (from www.cvshome.org).
  2. Download and install OpenSSH (from www.openssh.org or your distribution's specific download location).
  3. Create the directory for the CVS repository, for example
    mkdir /usr/local/cvsroot
  4. Initialise this directory (cvs will put a control module called CVSROOT under it)
    cvs -d /usr/local/cvsroot/ init
  5. Inform CVS of the location of this repository by adding a line to /etc/cvs/cvs.conf like so:
    CVS_REPOS="/usr/local/cvsroot"
  6. Enable remote access - you can enable this in a number of ways. Three methods will be discussed here - password CVS access over xinetd and inetd or more secure access over SSH.
    • CVS over SSH - a more secure option is to only allow access to your CVS server over SSH. For this you just need to install SSH and make sure that the user has SSH access and also had read/write access to the repository. To access CVS from a client you need to do the following:
      		setenv CVS_RSH ssh
      		setenv CVSROOT :ext:username@ipaddress.domain.com:/usr/local/cvsroot
      		
      There is no need to do a "cvs login" but you will be prompted for a password on each CVS command. To avoid this you can distribute your ssh-identity from the client to the server to allow automatic identification. For SSH2 change to your home directory (on your client machine) and generate RSA keys by issuing a command like so (might differ slightly depending on SSH installation, refer to man pages for exact syntax):
      ssh-keygen -t rsa
      This should prompt you to save 'your identification' in ~/.ssh/id_rsa.pub, press enter to do this and also press enter for the password and confirmation of it. (ssh 2) (or wherever $HOME points to), just hit enter. When asked for password and confirmation of password, continue hitting enter. Now you need to copy the public key generated by this command to the CVS server, for example using secure copy:
      scp .ssh/id_rsa.pub username@ipaddress.domain.com:~/.ssh
      Now log onto the CVS server and fix the authorized_keys file:
      		ssh developer@serverbox.domain.com
      		cd .ssh
      		cat id_rsa.pub >> authorized_keys2
      		chmod go-w authorized_keys2
      		
      You should now be able to ssh directly from the client to server without having to enter password, test this like so:
      ssh username@sipaddress.domain.com
      . It is important to bear in mind that this enables anyone with access to your client to continue into the server without knowing the password on the server! More information on CVS over SSH here.
    • pserver and xinetd - create (or edit) the file /etc/xinetd.d/cvs as follows:
      		service cvspserver
      		{
              	disable = no
              	socket_type         = stream
              	protocol            = tcp
              	wait                = no
              	user                = root
              	server              = /usr/sbin/cvspserver
              	server_args         = -f --allow-root=/usr/local/cvs/root pserver
      		}
      		
      Restart xinetd and you should now be able to access the CVS server remotely using authentication details of users already existing on the cvs server. You may need to enable your firewall to allow connections to CVS on it's default port (2401). To access CVS from a client you need to do the following:
      		setenv CVSROOT :pserver:username@ipaddress.domain.com:/usr/local/cvsroot
      		cvs login
      		
    • pserver and inetd - add the following line to the file /etc/inetd.conf as follows:
      		cvspserver stream tcp nowait root /usr/bin/env env -i /usr/bin/cvs -f --allow-root=/usr/local/cvsroot pserver
      		
      Restart inetd and you should now be able to access the CVS server remotely using authentication details of users already existing on the cvs server. You may need to enable your firewall to allow connections to CVS on its default port (2401). To access CVS from a client you need to do the following:
      		setenv CVSROOT :pserver:username@ipaddress.domain.com:/usr/local/cvsroot
      		cvs login
      		
File Management

Deleting zero length files [find]

find -maxdepth 1 -type f -size 0 -exec rm -f {} \;
Increase the value for maxdepth to control the number of directory levels you want to remove files under (or remove the parameter completely to remove all zero length files under all sub-folders).



Finding a string in multiple files [bash, grep]

For example, to find the text "foo" in all files under the current dir (recursively):
grep -r 'foo' *
For more usages of grep to search for strings in files see here



Performing an operation on all files of a certain type [find]

For example, moving all XML files in a folder and sub-folders to somewhere else (/some/folder):
find . -iname "*.xml" -type f -exec mv {} /some/folder \;
a possibly faster alternative is
find . -iname "*.xml" -type f | xargs -n1 -i mv {} /some/folder
or (for just the current folder)
for i in `ls *.xml`; do mv $i /some/folder; done




Replacing a string in multiple files [bash, find, perl]

For example, to replace the text "192.168.1.2" with "10.0.0.13" in all files with the name Root under all sub-dirs from the current dir:
find . -name Root | xargs perl -pi~ -e 's/192.168.1.2/10.0.0.13/'



Removing files/folders with a certain name [bash, find]

For example, to remove all the CVS folders from a CVS checkout, while leaving the other files and folders intact:
find . -name CVS | xargs rm -r



Removing files when rm complains about "Argument list too long" [bash, find]

For example, in a folder containing too many ".log" files to remove via rm, run a command like so:
find /some/folder/ -name "*.log" | xargs rm



Convert file names to lowercase [bash, tr]

A bash script which will convert all uppercase characters in all filenames in current directory to lowercase (can ignore errors for files which are already all lowercase):
	#!/bin/bash
	for file in *
		do newfile=`echo $file|tr [A-Z] [a-z]`
		echo "Moving $file to $newfile"
		mv $file $newfile
	done
	
An alternative is to use the command line rename utility like so
rename 'y/A-Z/a-z/' *



Renaming files [rename]

To find the text BLA in the filename and replace it with the text FOO in all .tgz files:
rename 's/BLA/FOO/' *.zip
To change the file extension of all .JPG files to .jpg:
rename 's/\.JPG/\.jpg/' *.JPG
To strip the spaces out of all filenames:
rename 's/ //' *.*
find . -name CVS | xargs rm -r



Splitting large files into smaller pieces (and reassembling them) [split, cat]

For example, to split a large gzipped tar archive with the name too.big.for.cdrom.backup.tgz into CD-ROM sized pieces of around 657MB you would issue the following command:
split -b 675000000
This creates files named xaa, xab, xac etc. - one for each chunk of 657MB. To restore the original file from these pieces, copy all the files to some location and issue the command
cat xa* >> too.big.for.cdrom.backup.tgz



Preventing locate from indexing certain folders [updatedb, locate]

To prevent certain folder from being indexed by "locate" add them to the PRUNE_PATHS list in the file
/etc/updatedb.conf



Find files that are changed after a certain moment of time (e.g. when installing a new program) [touch, find]

First, run
touch /tmp/now
Then run the program, then
find -newer /tmp/now
to get a list of all files that changed.

KDE

How to reset KDE menu

To reset the Menu delete this file:
~/.config/menus/applications-kmenuedit.menu
To rebuild KDE:
kbuildsycoca --noincremental



Quick Calculator

Press ALT-F2 (run command) and then type in your calculation


Configure Konqueror to open file and folders on DOUBLE click instead of annoying single click [KDE 3.2-3.5]

First, open the KDE control panel -> peripherals -> mouse and set it to double click to open files instead of single click. Then go into Konqueror -> Settings -> Configure Konqueror ->Appearance and uncheck the box "underline file names".


Configure Konqueror to not check for new plugins every time it starts

To improve startup of Konqueror, disable checking for Netscape plugins by going to Settings -> Configure Konqueror... -> Plugins and then look for the tab "Scan" under "Netscape plugins" and uncheck the box "Scan for new plugins at KDE startup". If you add new plugins you will need to remember to re-enable this if you want them detected. Also double check that the
/usr/bin/startkde
script does not contain a call to "nspluginscan".

Multimedia

Create CD audio tracks from mp3 [mpg123]

From the command line:
mpg123 (mpg123 -cdr -s file1.mp3 | cdrecord -nofix dev=0,0,0
Last command is fix instead of nofix (?)



Create .cdr tracks from other audio formats [sox]

Use a command line app called sox. cdrecord also supports this natively, see man pages.



Stretch MPlayer video to fit screen

Add the following to
~/.mplayer/config
	 zoom=1
	 vo=xv
	 
Networking

Connecting 2 machines using a crossover cable

Sharing an internet connection with 2 computers (A and B) using Computer A as the gateway and Computer B as the second machine. Computer A needs 2 network cards: One network card must be configured appropriately for "normal" internet access from this machine (i.e. connected to cable, ADSL etc.); the second network card must be manually configured as shown below. Setup computer A's second network card's networking configuration like so:
	IP address: 192.168.1.1
	Netmask: 255.255.255.0
	Gateway: 192.168.1.255
	
Computer B only needs one network card, setup like so:
	IP address: 192.168.1.2
	Netmask: 255.255.255.0
	Gateway: 192.168.1.1
	
Connect computer A's second and computer B's only network cards directly to each other using a CROSSOVER cable.

Below covers further configuration if Computer A is running SUSE Linux 9.1 as the gateway as it needs additional configuration. eth0 is the network card connected to the internet and eth1 is the network card connected to computer B via the crossover cable.

  1. Open Yast2 and go to -> Security and Users -> Firewall
  2. Set address of eth0 to "external interface" and address of eth1 to "internal interface" and click next
  3. Configure services that need to be run on the linux machine (if any). Click next
  4. Select "Forward Traffic & Do Masquerading" and deselect "Protect from internal network". Leave others as default or needed. Click next
  5. I left everything as default on this screen. Click next
  6. Firewall settings will be reset and networking should be available on second machine


General Samba stuff

Samba configuration utility: KSambaPlugin
Samba tutorial
Can create shares by right-clicking folders in Konqueror.

Package Management

APT in a nutshell

To install a package named X:
apt-get install X
To do a dummy run of an installation a package named X (nothing will be installed, useful to check that an installation won't have any problems):
apt-get install X -s
To uninstall a package named X, but leave its configuration files in place:
apt-get remove X
To uninstall a package named X and all its related files:
apt-get --purge remove X
To remove orphaned packaged:
apt-get autoremove
Search all installed packages and check whether there are any broken dependencies (useful to run from time to time):
apt-get check
To get the latest package information from the source in the apt sources.list:
apt-get update
To upgrade to the latest package versions obtained from running the above command:
apt-get upgrade
To search for a package:
apt-cache search X
The above command accepts regular expressions as the argument so to search for package starting with X use ^X and ending with X use X$ etc.

To see which package a file belongs to:
apt-file update
apt-file search SOMEFILE
To do the opposite and see which files a package provides:
apt-file list Y
To improve the performance of APT downloads you can select mirrors by using "netselect-apt". When it is run it will check the mirrors from debian and ping them and save a new sources.list file in the current directory with the fastest mirrors.

To do a dump of all the software currently installed run
dpkg --get-selections > SOMEFILE
If you save this to a file you can restore it later (e.g. on a different machine) by running
dpkg --set-selections < SOMEFILE
apt-get dselect-upgrade
To clean up APT's cache, you can manually remove files from
/var/cache/apt
but a better solution is to use APT to do this, first to clean up packages that it considers old:
apt-get autoclean
Or to delete them all:
apt-get clean



rpmdbNextIterator errors [SUSE 9.1]

When running rpm commands, errors occur like so:
error: rpmdbNextIterator: skipping h# 709 Header V3 DSA signature: BAD, key ID cd3140cd
As root, run the following command:
rpm --rebuilddb

Security/SSH

SSH via an intermediate machine

Certain firewall setups allow one to SSH only onto a single machine (e.g. somehost1.com) and from there one can then SSH onto another machine (e.g. somehost2.com) (i.e. direct SSH to somehost2.com is not possible). In order to SSH to somehost2.com without having to first SSH onto somehost1.com, create a command called something like sssh as follows:
ssh -oproxycommand="ssh -q somehost1.com nc %h %p" $*
If you have set up SSH key access to somehost1.com you can now SSH onto somehost2.com from the machine with direct access only to somehost1.com like so:
sssh user@somehost2.com
and only be prompted for somehost2.com's password.



SCP through an intermediate machine

In a similar vein to the above tip, you can create a very similar command to allow you to SCP to somehost2.com via somehost1.com without having to first SCP onto somehost1.com and from there onto somehost2.com. Create a command (call it sscp) like so:
scp -oproxycommand="ssh -q somehost1.com nc %h %p" $*
and use it like so:
sscp someLocalFile user@somehost2.com:/remote/path



X forwarding over SSH

To run GUI programs on one machine using another machine one can use X forwarding by connecting using
ssh -X user@remotecomputer
and once logged in running the command to start the GUI app, the GUI window will open on the local machine. X11Forwarding must be enabled in the file
/etc/ssh/sshd_config
(which is usually the base by default). To speed things up -Y (Trusted X11Forwarding) or -C (compression) can be used instead of -X.



Monitor SSH login failures

It is worthwhile to periodically check the contents of the file
/var/log/auth.log
for failed SSH connections. This might indicate someone attempting a brute force attack etc.

Shell/CLI

Running multiple commands [bash]

To run a number of commands sequentially, put a ";" between each:
./configure; make; make install
To run a command only if the one before succeeds, use "&&" between them instead:
./configure && make && make install
Similarly to run a command only if the one before it fails, use "||":
./configure || echo "Configure failed"



Creating a .tgz file [tar]

For example, to create a gzipped tar archive with the name foo.tgz of all the contents of the current dir:
tar -czvf foo.tgz *



Determining disk usage [du]

The easiest way to determine how much space your files and directories are taking up is to use the following command:
du -sH * .[a-zA-Z]*
For a quick way to find the biggest ones, try:
du -sH * .[a-zA-Z]* | grep "[0-9]MB"



Reload environment variables [bash]

If you set the variables in .bashrc, issue the command:
source .bashrc



Screen cheet sheat [screen]

Create a new screen session with a certain name:
screen -S screenName
Reattach to a screen by name:
screen -x screenName
Create a new screen:
CTRL-A c
Moving between more than one open screen:
CTRL-A 0/1/2/3 etc.
To scroll back through program output in a screen:
CTRL-A ESC
(push ESC again to go back).
To name a screen window/tab:
CTRL-A A name



Using environment variables [bash]

!$ represents the last word of previous command in your history.

$* represents all command line arguments passed to a command.




Redirecting input and output

Use > to take output from a command to a file:
cat bla > results.txt
This will take the results from cat and put them in a file called results.txt, overwriting results.txt if it exists. To append the output instead of overwriting, one can use >>:
cat bla >> results.txt
Use < to take input into a command:
grep -i X < someFile.txt
This will look for the string "X" in someFile. One can place a number before ">" to direct standard input/output where 0=standard input, 1=standard output, 2 =standard error output. This can be used, for example, to see results of a command sent to standard out while ignoring any errors. e.g. if we run "find" but want to ignore errors (e.g. permissions errors etc). we can redirect error output to /dev/null leaving us with what we are interested in (the standard output):
find / -name *.jpg 2>/dev/null



Silence the system bell in a console

Issue the command:
setterm -blength 0



Determine which processes are running on which ports

Issue the command to see a list of open sockets and pid/program names:
netstat -p



Determine memory usage

Issue the command:
cat /proc/meminfo
(top might also be useful)



Adding paths to library path

As root, add the required paths to
/etc/ld.so.conf
and then run
ldconfig



Determine kernel version [uname]

Issue the command:
uname -a



See status of modules loaded by kernel [lsmod]

Issue the command:
lsmod

Startup

Removing default splash/boot screen [SUSE 9.1, 10.1 GRUB boot loader]

As root, open the file
/boot/grub/menu.lst
and change the relevant item to
splash=verbose
On SuSe 10.1 you also need to modify the file
/etc/sysconfig/bootsplash
and add/set the configuration parameter
set SPLASH="no"



Booting into console instead of default X [SUSE 9.1, GRUB boot loader]

Either manually change boot image from
linux
to
linux 2
on the main GRUB boot screen. Another option is to change the default run level specified in
/etc/inittab
e.g.
id:2:initdefault:


SUSE 9.1 Errors

Eclipse fails to start (pango) [SUSE 9.1, Eclipse, Pango]

Eclipse fails to startup and get this error message in log:
	An unexpected exception has been detected in native code outside the VM.
	Unexpected Signal : 11 occurred at PC=0x5A347149
	Function=(null)+0x5A347149
	Library=/opt/gnome/lib/pango/1.4.0/modules/pango-hangul-fc.so

	NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

	Current Java thread:
        at org.eclipse.swt.internal.gtk.OS.pango_layout_get_iter(Native Method)
        - locked <0x54ad4358> (a java.lang.Class)
	
To solve this, downgrade the pango library from version
1.4.0-100.SuSE.ulb.1(stable)
to
1.4.0-9(stable)



Unable to write DVD's using K3B [K3B, SUSE 9.1]

When trying to burn a DVD using K3B on SuSe 9.1 I got this error:
umount: only root can unmount /dev/dvdrecorder from /media/dvdrecorder k3b
To get rid of this error, check the fstab settings (in /etc/fstab for your dvd burner, most likely a normal user is not allowed to burn dvd's. Edit /etc/fstab and add users to the "fs" parameter, e.g.
/dev/dvdrecorder /media/dvdrecorder subfs fs=cdfss,ro,users,procuid,nosuid,nodev,exec,iocharset=utf8 0 0
After doing this I then got this error:
:-( unable to PREVENT MEDIA REMOVAL: Operation not permitted k3b
I'm not sure how to fix this, so I was forced to run K3B as root for burning DVD's and then it worked.



Gtk-WARNING **: Unable to locate theme engine in module_path: "qtpixmap" [SUSE 9.1, GTK]

Get this error message on startup of various programs (particularly eclipse) after upgrading various gnome and kde packages using apt-get which upgraded GTK from 2.2.0 to 2.4.0. Apparently what has happened is that the theme engine module_path now looks in
/opt/gnome/lib/gtk-2.0/2.4.0/engines
for theme engines, whereas it used to look in
/opt/gnome/lib/gtk-2.0/2.2.0/engines
. The qtpixmap engines are in the 2.2.0 folder but not the 2.4.0 folder. So symlinking to them from the 2.4.0 folder seems to solve this issue like so:
cd /opt/gnome/lib/gtk-2.0/2.4.0/engines
ln -s ../../2.2.0/engines/libqtpixmap.so
ln -s ../../2.2.0/engines/libqtpixmap.la
Restart eclipse and it gets QT look and feel and erorr message goes away on start.

Various Errors (and their solutions)

X "connection refused" errors [X windows]

The error message is usually something like 'Xlib: connection to ":0.0" refused by server'. This occurs when you try start an X application as a user other than the user which started X so the authentication keys differ. The first thing to try is
xhost +local:local
as the user who started the x session (usually the user you logged in to X as) before you switch to a new user. This can be added to .bashrc to always allow local (i.e. not over a network) X connections by all users. Some Linux distributions allow you to start X applications as root by starting the root shell using
sux
instead of
su