Perl Scripting: Check If a File Exists

It’s not often that I write about Perl Scripting on Unix Tutorial, but that’s just because I don’t script in Perl this much on a regular basis. Today, however, I’d like to share one of the building blocks – a really basic piece of functionality which you’ll find really useful in almost any Perl script.

How to check if a file exists in Perl

First of all, we need to create one file for our experiments:

ubuntu$ touch /tmp/file.try

Now, create a new file with our script: /tmp/file-try.pl (don’t forget to chmod a+x /tmp/file-try.pl afterwards to make it executable):

#!/usr/bin/perl
#
$FILE1="/tmp/file.try";
$FILE2="/tmp/file2.try";
#
if (-e $FILE1) {
        print "File $FILE1 exists!\n";} else {
        print "File $FILE1 is not found!\n";
}
if (-e $FILE2) {
        print "File $FILE2 exists!\n";
} else {
        print "File $FILE2 is not found!\n";
}

Now, as you can see from the example, the actual condition checking for the existence of a file is this:

if (-e $FILE)

where $FILE is the string containing the filename.

In my example, there’s two filenames ($FILE1 and $FILE2) and two conditions, so that you can see for yourself how one of them confirms the existence of a file and another one proves that there’s no such file found.

To see the script work, simply run it without any parameters:

ubuntu$ /tmp/file-try.pl
File /tmp/file.try exists!
File /tmp/file2.try is not found!

That’s all for today! Enjoy your Perl scripting!

See also:




List drives by UUID in Ubuntu

Having used this tip a few times myself, I’d like to share it with you: a very simple way to list all the drives in your Ubuntu system using their UUID’s.

Disks by uuid in Ubuntu

Apart from blkid command, there’s another relatively easy way for you to confirm what each UUID on your system corresponds to. If you look in the /dev/disk/by-uuid directory, it contains symlinks which look like UUIDs and point to the real devices for each of your disks:

ubuntu# ls -al /dev/disk/by-uuid/*
lrwxrwxrwx 1 root root 10 Jan 12 04:25 /dev/disk/by-uuid/2596b3b4-9e54-47e2-bb45-89b3d4a0e7e3 -> ../../sda2
lrwxrwxrwx 1 root root 10 Jan 12 04:25 /dev/disk/by-uuid/d2ff8a06-74b7-4877-9d37-1873414e25b3 -> ../../sda1

Confirm disk device using its UUID

Knowing the /dev/disk/by-uuid directory, you can easily use this to look disks up by their UUID with the readlink command:

ubuntu# readlink /dev/disk/by-uuid/d2ff8a06-74b7-4877-9d37-1873414e25b3
../../sda1

That’s it! Have a great week!

See also:




Updates in Unix Glossary

Just updated the Unix Glossary section with the following definitions:

There’s no way these will be final, and so I’ll be updating them now and them so stay tuned. For example, the Unix definition is still not in the glossary, because I’m struggling with wording the paragraph for it. Will add next week, for sure!

See Also




Unix Tutorial Digest – January 22nd, 2009

Now that I’m finally back into my usual posting and reading other blogs, I think it’s a good time to restart the “Interesting Reads”. Here are the Unix articles you might like:
* Tools to delete files securely in Ubuntu
* List installed packages in Ubuntu – some more tricks in addition to my original article
* Unmounting unresponsive CD/DVD drive in Linux Enjoy these useful Linux tips! If you have any useful articles you’d like to share – just leave links in the comments area.




New section added: Unix Glossary

I’ve just created another section on Unix Tutorial – the Unix Glossary, which is a section I’m going to use for listing definitions to all the topics I briefly touch in my regular posts.

So far, there’s only one item there – runlevel definition. Obviously, it’s a work in progress, so I’ll be updating definitions constantly and expanding the section as I post more.

The plan is to have a Unix Glossary section at the bottom of each post on Unix Tutorial, so that it gives you another chance to expand your understanding of Unix basics.

If you have any terms from Unix world which you’d like me to cover first, please head over to the Unix Glossary page and leave a comment there with your suggestions.

Let me know what you think about this, do you think it will help? If there’s any other side of this blog you’d like changed or improved – just let me know. I’m using this blog as my own reference all the time, so I always appreciate your feedback as it makes life easier and Unix Tutorial better for everyone.




Want to Learn Unix with me?

As I plan my goals for 2009, I’m thinking of making a few self-paced courses for all the readers of this blog.

I think it’s about time some of the basics are covered in a format of a course, complete with structured material and examples and with some multiple-choices testing.

If you want to learn Unix

If you’re interested in anything like this, please leave comments or contact me directly with your suggestions for course topics and desired structure. Also, if you’re keen in becoming a member – join the Unix Tutorial waiting list right now!

Unix Tutorials – self-paced courses

So far, the most popular topics and therefore the first candidates for courses are the following:

  • Unix shell scripting
  • Finding files and directories in Unix
  • Unix users and groups
  • File ownership and access permissions
  • rsync tutorial
  • sudo tutotial
  • unix sockets
  • comparing files in Unix

Have you got an idea for a great Unix tutorial? Let me know and I’ll see what I can do.

See also




Disable a startup of service in Ubuntu

If for whatever reason you stop using a certain service in your Ubuntu install and would like to disable automatic restarting for it upon system reboot, all it takes to do it is just one command line.

Startup and shutdown scripts in Unix

In most Unix distros, the startup and shutdown sequences of various system services are managed using a set of startup and shutdown scripts.

Startup scripts a’re usually located either in /etc/init.d or in /etc/rc.d/init.d/ directories (sometimes /etc/init.d is a symlink to /etc/rc.d/init.d). On top of these directories, they’re also a set of directories for each of your system runlevels: /etc/rc0.d, /etc/rc1.d, /etc/rc3.d, etc.

The reason scripts are organized this way is because in runlevel specific directories you only have symbolic links referring to the original script in /etc/init.d. Each of the scripts in this directory usually caters for a number of scenarios: starting a service up, stopping it, and, optionally, restarting it (which is the same as stopping/starting sequence in most cases).

As your Unix OS goes from one runlevel to another following a startup or shutdown, it looks for symlinks in /etc/rc*.d directories and uses them to ensure the services specified there are started or stopped accordingly.

Promise: One day, I will certainly spend more time talking about the Unix OS startup process itself, but for today I just want to concentrate on the scripts for a particular service.

So, for the FTP service, I have the /etc/init.d/proftpd startup/shutdown script plus the following set of symlinks referring to it:

/etc/rc0.d/K20proftpd -> ../init.d/proftpd
/etc/rc1.d/K20proftpd -> ../init.d/proftpd
/etc/rc6.d/K20proftpd -> ../init.d/proftpd
/etc/rc2.d/S20proftpd -> ../init.d/proftpd
/etc/rc3.d/S20proftpd -> ../init.d/proftpd
/etc/rc4.d/S20proftpd -> ../init.d/proftpd
/etc/rc5.d/S20proftpd -> ../init.d/proftpd

If you look at any of them, you can see that they really are symlinks:

ubuntu# ls -l /etc/rc3.d/S20proftpd
lrwxrwxrwx 1 root root 17 Jan 13 03:39 /etc/rc3.d/S20proftpd -> ../init.d/proftpd

Disabling startup of a service in Ubuntu

The procedure for disabling a service in Ubuntu is very simple: all you have to do is remove the symlinks from all the runlevel-specific directories, /etc/rc*.d, so that no links are pointing to the original /etc/init.d script for your service. That original script will be kept, so you can re-enable the startup/shutdown of the service whenever you feel like using it again.

This example below shows how a service called “proftpd” was disabled on my system:

ubuntu# update-rc.d -f proftpd remove
Removing any system startup links for /etc/init.d/proftpd ...
/etc/rc0.d/K50proftpd
/etc/rc1.d/K50proftpd
/etc/rc2.d/S50proftpd
/etc/rc3.d/S50proftpd
/etc/rc4.d/S50proftpd
/etc/rc5.d/S50proftpd
/etc/rc6.d/K50proftpd

You obviously don’t have to reboot your system just to stop your service though, so instead you can simply do this:

ubuntu# /etc/init.d/proftpd stop
 * Stopping ftp server proftpd

That’s all there is to it! Good luck with disabling the unused services!

Recommended books:

See also:

Unix glossary




How to see future file timestamps in Solaris

I know I’ve spoken about timestamps already, but I’d like to further expand the topic.

While there’s a great GNU stat command in Linux systems, there’s no such thing in Solaris by default, and so you usually depend on ls command with various options to look at file’s creation, modification or access time.

The standard /bin/ls command in Solaris doesn’t always show you the full timpestamp, usually if it’s about a time too far in the past or a bit into the future – so today I’m going to show you a trick to work around it and still confirm such timestamps for any file.

Standard ls command in Solaris doesn’t always show full timestamps

Here’s an example: BigBrother monitoring suite creates np_ files for internal tracking of times to send out email notifications. It deliberately alters the timestamps so that they’re set for a future date – that’s how it tracks the time elapsed between the event and the next notification about it.

However, not all of these np_ files are shown with their full timestamps, some just show the date, with no time:

solaris$ ls -l *myserver1*
-rw-r--r--   1 bbuser   bbgroup       48 Jan  9  2009 [email protected]_myserver1.conn
-rw-r--r--   1 bbuser   bbgroup       50 Jan  9 10:41 [email protected]_myserver1.cpu
-rw-r--r--   1 bbuser   bbgroup       51 Jan  9 10:41 [email protected]_myserver1.disk
-rw-r--r--   1 bbuser   bbgroup       53 Jan  9 10:36 [email protected]_myserver1.memory
-rw-r--r--   1 bbuser   bbgroup       51 Jan  9 10:41 [email protected]_myserver1.msgs
-rw-r--r--   1 bbuser   bbgroup       52 Jan  9  2009 [email protected]_myserver1.procs

If you remember, the default behaviour for ls is to show the modification time of each file. So in this example you can see that two files only have the date, and not the time of their modification timestamps shown. For other files, the full timestamp is present.

Before we continue, let’s confirm the current time on this Solaris server:

solaris$ date
Fri Jan  9 10:44:06 GMT 2009

For the two files with only date shown,  ls recognizes that the file can’t really have a future modification timestamp, and only shows the part is agrees with – the date which is valid (today).

What can we do? First, double-check other times – like the creation time of these files:

solaris$ ls -lc *myserver1*
-rw-r--r--   1 bbuser   bbgroup       48 Jan  9 10:14 [email protected]_myserver1.conn
-rw-r--r--   1 bbuser   bbgroup       50 Jan  9 09:56 [email protected]_myserver1.cpu
-rw-r--r--   1 bbuser   bbgroup       51 Jan  9 09:56 [email protected]_myserver1.disk
-rw-r--r--   1 bbuser   bbgroup       53 Jan  9 09:51 [email protected]_myserver1.memory
-rw-r--r--   1 bbuser   bbgroup       51 Jan  9 09:56 [email protected]_myserver1.msgs
-rw-r--r--   1 bbuser   bbgroup       52 Jan  9 10:31 [email protected]_myserver1.procs

All of them are showing correct full timestamps from some time in the past, so that’s okay.

How to show future timestamps in Solaris

And now comes the moment to reveal the little trick I was talking about. Even though the standard /bin/ls command won’t show you the future timestamps, you can still check them using the /usr/ucb/ls version of the ls command. The syntax is very similar, but you can also see the future timestamps:

solaris$ /usr/ucb/ls -al *myserver1*
-rw-r--r--   1 bbuser         48 Jan  9 10:59 [email protected]_myserver1.conn
-rw-r--r--   1 bbuser         50 Jan  9 10:41 [email protected]_myserver1.cpu
-rw-r--r--   1 bbuser         51 Jan  9 10:41 [email protected]_myserver1.disk
-rw-r--r--   1 bbuser         53 Jan  9 10:36 [email protected]_myserver1.memory
-rw-r--r--   1 bbuser         51 Jan  9 10:41 [email protected]_myserver1.msgs
-rw-r--r--   1 bbuser         52 Jan  9 11:16 [email protected]_myserver1.procs

Looking at them, you can see that BigBrother simply set the modification time for these files to be 45min into the future.

That’s it for today – hope you liked this trick!

See also:




How To Check if Any Users Were Added or Deleted on Your Linux System

Yesterday in my post on numeric userids instead of usernames, I touched briefly the problem of recovering the username if you only know the userid it once had. Today I would like to show you another option which may be available to you when it comes to recovering the usernames of removed users by their userid.

useradd and userdel logs in Ubuntu

Both useradd and userdel commands keep logs in many Unix-like systems. This means that every newly created user gets the whole procedure documented in appropriate logs with lines similar to this (it’s an Ubuntu example, /var/log/auth.log file):

Jan  6 04:24:27 simplyunix useradd[1456]: new group: name=mike, GID=1006
Jan  6 04:24:27 simplyunix useradd[1456]: new user: name=mike, UID=1006, GID=1006, home=/home/mike, shell=/bin/sh

Similarly, deleting a file doesn’t go unnoticed neither:

Jan  6 04:29:21 simplyunix userdel[1516]: delete user `mike'
Jan  6 04:29:21 simplyunix userdel[1516]: delete `mike' from group `admin'
Jan  6 04:29:21 simplyunix userdel[1516]: removed group `mike' owned by `mike'

So, there’s a chance that by simply going through /var/log/auth.log you will find the userid of a local Unix user which was recently removed. But the reason I won’t say “there’s a really good chance” is because most of the logs in /var/log are rotated on a weekly and monthly basis, and this means the information about new users created or deleted may not be there at the time you go looking for it – anyone who was added or deleted more than few months ago will not show up.

useradd and userdel in RedHat Enterprise Linux

Similar to Ubuntu, you can find recent user management activity logged in RHEL system, in /var/log/secure file.

useradd will produce something link this:

Jan  8 00:18:36 rhel5 useradd[2674]: new group: name=newuser, GID=501
Jan  8 00:18:36 rhel5 useradd[2674]: new user: name=newuser, UID=501, GID=501, home=/home/newuser, shell=/bin/bash

… while userdel will document its actions with the following:

Jan  8 00:18:40 rhel5 userdel[2682]: delete user `newuser'
Jan  8 00:18:40 rhel5 userdel[2682]: removed group `newuser' owned by `newuser'

How to check if any users were added on your Unix system

Based on the information above, all you have to do is something like this:

ubuntu$ grep useradd /var/log/* 

This is bound to return you a list of all the recently added users.

How to confirm local users which were recently removed

Similarly, use a command like this to find out if any users were recently removed:

ubuntu$ grep userdel /var/log/* 

Hope this helps! Enjoy!

See also:




What to do if numeric id is shown instead of Unix username

As you know, every file in your Unix OS belongs to some user and some group. It is very easy to confirm the ownership of any file because user id and group id which own the file are always linked to the file. However, sometimes you can’t tell which user owns the file, and today I’m going to explain why. It’s a rather lengthy post and a complicated matter, so please leave questions or comments to help me polish this article off.

Files and directories ownership in Unix

If you look at any file using ls command, you will see an output like the one shown below – it reveals file access permissions, user and group id of the owner, the modification timestamp and the file name itself:

ubuntu$ ls -l /tmp/myfile
-rw-r--r-- 1 greys admin 0 Jan  6 03:51 /tmp/myfile

In this example, the /tmp/myfile file belongs to me, hence the username is greys. It also belongs to my default (primary) Unix group – admin.

Similarly, ownership of any file or any directory can be confirmed for every object in available filesystems. Here’s just a few more examples, these are the standard system files belonging to root:

ubuntu$ ls -ald /etc /etc/passwd
drwxr-xr-x 91 root root 4096 Jan  6 03:51 /etc
-rw-r--r--  1 root root 1481 Jan  6 03:51 /etc/passwd

Why numeric IDs are sometimes shown instead of username or groupname

Sometimes though, you will look at a file and instead of the username you will see a numeric ID:

ubuntu# ls -al /tmp/file
-rw-r--r-- 1 1006 root 0 Jan  6 03:51 /tmp/file

The reason numberic ID (1006 in the example above) is shown instead of a username is because your system doesn’t recognize this ID – it can’t be associated to any username known to your Unix OS.

There are a few possible scenarios for this to happen, but most likely the user has been removed since the file was created. Naturally, deleting any User doesn’t automatically mean removing every single file belonging to such a user, that’s why the files stay but can no longer be associated with the existing user. All they have to show is the user ID which once owned the file.

How to find the missing username using user id

Unfortunately, there are no easy ways to recover the username (or any other user-specific information) based on a misterious user ID some of your files might have. There are a few things can try though.

  1. Try other Unix systems in your environment

    It can be the case that Unix account was a local one automatically created by your system administrators. There’s still a chance the same uid exists on other systems. Log into a few of them and verify if they have a user with the same user id (read this post for more information: How to Find Out user id):

    ubuntu$ getent passwd 1006
    newowner:x:1006:1006::/home/newowner:/bin/sh

    The same tip applies in case of more mature environments where Unix systems don’t have local users, but instead rely on NIS or LDAP for accessing user accounts information.

    If your system for whatever reason can’t access the centralized storage for users, you will experience the same symptoms – most of files belonging to users will appear to have numeric IDs instead of usernames. Most likely though, you’ll have more important problems in this case – like not being able to log in as anything else but root (which is an administrative account always created locally on each system).

  2. Look at home directories and their owners

    When a new user is added to Unix system, it usually gets a home directory assigned to it. Creating a home directory is not a default behaviour at times, but it’s a good practice and so there’s a very high probability that the user you’re looking for had a home directory. Removing home directories isn’t usually done at the same time when a user is removed, so there’s also a good chance that even though the user isn’t found anymore, the home directory is still there.

    What you should be looking for is a home directory which belongs to the same user id which some of the unidentified files of yours belong to.

    Simply do an ls command under /home directory and see if any of the directories there appear to have numeric IDs instead of usernames:

    ubuntu# ls -ald /home/*
    drwxr-xr-x  2 ftp   nogroup  4096 May 22  2007 /home/ftp
    drwxr-xr-x 11 greys greys    4096 Dec 13 19:56 /home/greys
    drwxr-xr-x  2 1006  admin    4096 Jan  6 04:23 /home/mike

    As you can see, sometimes you might get lucky – the directory is there, and since most home directories usually have the same name as the username which owns them, you can deduct that the username of the user id 1006 was “mike“. You can now recreate Mike’s account and it will be immediately reflected for all the files owned by user id 1006:

    ubuntu# ls -ald /home/mike
    drwxr-xr-x 2 1006 admin 4096 Jan  6 04:23 /home/mike
    root@simplyunix:~# useradd -u 1006 mike
    root@simplyunix:~# ls -ald /home/mike /tmp/file
    drwxr-xr-x 2 mike admin 4096 Jan  6 04:23 /home/mike
    -rw-r--r-- 1 mike root 0 Jan  6 03:51 /tmp/file
  3. Look at other users known to your systemSometimes users are created in batches, and you can guess who the user was by looking which users were created before and after. All you have to do is to use the same getent passwd approach for user ids which are smaller or larger than the one you want to identify.

    Another way to user other users’ information to your advantage is to verify which groups they belong to and to then query the groups to see if they have any members not currently known to your system. This will only work for NIS/LDAP groups, not local ones. What could happen is that even though a user was removed, the username is still listed in a few NIS groups.

That’s it for today. Hope this post helps you in your investigations, and stay tuned for more!

See also: