Killing zombies
Killing zombies
If you spend any time looking at your process list, sooner or later you're going to come across one that's labelled 'defunct'. Before we explain what a defunct process is and how to remove it, here's a brief overview of how to query the process table using the ps command.
Typing ps ux will list all the processes attributed to the current user, and you can specify another user name with ps U username. One of the most common uses for ps is to list all the processes running on the system, and this can be achieved by using ps aux. Breaking this command down, the a will list all the processes rather than those of a single user, the u is the level of details returned for each process, and x lists processes such as daemons that weren't started from a terminal.
A defunct process is one that was started by another process (the parent), but has finished without the parent waiting for completion. This can happen if the parent process has hung or crashed.
Defunct processes are also known as zombies, and listed with a 'Z' status in the output from ps. They're not quite as destructive as the living dead, as they consume almost no system resources, but on a system that's always turned on, such as a server, they can become equally distracting. The key to killing a defunct process is to first kill the parent, which will be listed in the output of ps with the addition of -l for long output. Parent processes can be identified under the PPID column, as opposed to the PID column for the process ID. These are identifiers attached to each process running on your system. They can be killed using another common shell command, kill -9, followed by the PPID. Obviously this will stop the parent task, so first make sure it's not essential. Once the parent process has been killed, the system init process should send the correct signal to the defunct process, which should terminate automatically.
Safe keys
We rely on encryption to keep our data safe, but this means we have various keys and passphrases we need to look after. A GPG key has a passphrase to protect it, but what about filesystem keys or SSH authentication keys. Keeping copies of them on a USB stick may seem like a good idea, until you lose the stick and all your keys enter the public domain. Even the GPG key is not safe, as it is obvious what it is and the passphrase could be cracked with a dictionary attack.
An encrypted archive of your sensitive data has a couple of advantages: it protects everything with a password (adding a second layer of encryption in the case of a GPG key) and it disguises the contents of the file. Someone finding your USB key would see a data file with no indication of its contents. Ccrypt (http://ccrypt.sourceforge.net) is a good choice for this, as it give strong encryption and can be used to encrypt tar streams, such as
tar -c file1 file2... | ccencrypt >stuff
and extract with
ccdecrypt <stuff | tar x
If you really want to hide your data, use Steghide (http://steghide.sourceforge.net) to hide the data within another file, such as a photo or music file
steghide embed --embedfile stuff --coverfile img_1416.jpg
and extract it with
steghide extract --stegofile img_1416.jpg
A history lesson
While command completion is one of the most used and lauded aspects of Bash, an equally powerful feature often gets ignored. The history buffer, commonly used for skipping backwards and forwards through the previous commands list, offers plenty more possibilities than might otherwise be imagined. While it's easy enough to cursor up through the list, sometimes the command can be so far back in the history as to make this approach unfeasible. The history command can print the whole buffer to the screen. The most obvious use for this is to redirect the command's output into grep to find a partially remembered command.
$ history | grep "command"
If the command is still in the buffer it will be displayed along with the numeric position it occupies. This command can then be re-executed simply by taking this number and prefixing an exclamation mark to the position. For example, !1016 would execute the command at point 1016 in Bash's history. Another trick is to follow the exclamation mark with part of a previous command. The history will then be searched and when a match occurs, this will be executed.
!cd would execute the last cd command in the buffer. Sadly, these commands don't add themselves to the history buffer, so recursive execution isn't possible. Another way of accessing the command history is through the search function accessed by pressing Ctrl-R from the prompt. After pressing this control sequence, you will be presented with a search prompt. Typing in the search term brings up the first command that matches the criteria, and pressing return will execute the command. Cursor left or right will insert the command on to the prompt, while up and down takes you to the previous and next commands as usual.
Winning arguments
We can't teach you how to be the victor in every debate, but we can show you how to master another type of argument: those of the command-line. You probably already know about supplying multiple arguments to a program, for instance:
someprog file1 file2 file3
That's all good and well when you're entering commands by hand, but what if you want to use a list generated by another program? Say, for example, you want Gimp to open the ten largest images in a directory. You could do an ls -l to find out what's biggest, and then laboriously enter each filename as in gimp file1 file2... Or you could use the magic that is xargs (included in every distro).
ls -S --color=never | head -n10 | xargs gimp
xargs assembles complicated command-line operations using lists of files, so you don't have to type them manually. You pass xargs a list of files, and it arranges them into file1 file2 file3... as we saw before. Makes sense? Consider the above example. First we use ls to generate a list of files in the current directory (making sure we disable the colour codes as they produce unwanted characters). Then, using the good old pipe (|), we send the results to the head utility, which grabs the first ten entries.
So now we have a list of ten files. How do we tell Gimp that we want it to open them? We can't just directly pipe the results of head through, because Gimp would think it was raw graphics data. This is where the addition of xargs saves the day: it ensures that the following program name uses the data as a filename list, rather than trying to work with it directly. In our example above, it says "Take the top ten list as generated by head, and then pass it to Gimp in the traditional file1 file2 file3... format. You can do lots of things with xargs, all it expects is a list of files, separated by newline characters or spaces. As another example, this line deletes all files older than ten days (use with caution!):
find . -mtime +10 | xargs rm
0 comments:
Post a Comment