Port Perl scripts from Solaris to Linux

A guide for code remediation when direct mapping is just not available


With advances in visualization technologies, enterprises are consolidating physical servers into virtualized environments and thus improving asset management while reducing power consumption and physical space. In some cases, consolidation movements involve migrating from an old operating system to one that can provide easier system maintenance or other Total Cost of Ownership benefits.

If you are planning to migrate from Solaris to Linux, then almost all of your custom code (including C, shell scripts, Perl, etc.) will need some sort of remediation—a "realignment"of mapping attributes—due to differences in platforms.

Moreover, Perl is not different from other languages—although the program itself is portable among platforms, and you just need an installed interpreter to run the code on the target system—some remediation-type issues will probably arise. Solaris-specific resources, most notably operating system pathnames, system commands, and Perl modules, are often leveraged in the code. So you should expect to have to make some code remediation to ensure that Perl scripts work as intended after the migration.

But what Perl syntax constructs and which operators should you pay most attention to? In this article, we explain the most common portability pitfalls and present a roadmap for migrating Perl scripts from Solaris to Linux. You could probably use the roadmap in this article on migrations from most UNIX operating systems (including AIX, HP/UX, etc.) to Linux; however, all examples, sample code, and references are focused on Solaris to Linux migrations.

Perl portability issues

You should inspect resources referenced on Perl scripts to ensure that no problems due Solaris-specific code will arise when running them on a Linux system. For example, think about a script that extracts information from a file that is encountered only on Solaris; imagine executing a system command that uses a flag that is not available on Linux.

Most portability issues can be divided into five classes based on the system resources they access or reference, as listed in Table 1.

Table 1. Classes of portability issues in Perl scripts
ClassPortability issue
01Platform-specific Perl modules dependency
02Operating system commands and IPC (inter-process communication)
03Leveraged operating system pathnames
04Use of special variables that hold platform-specific information
05Functions that are implemented differently or not implemented across platforms

The classes listed in Table 1 are not a definitive list of all portability issues but rather just the most common ones. For more detailed information about portability problems, take a look at Perl Programming Documentation (see Related topics for a link).

Five steps to perfect Perl porting

Let's look at the roadmap to porting Perl scripts from Solaris to Linux. This roadmap builds on the classes of portability issues in Table 1. The roadmap includes five steps, each one focusing on one of the classes from Table 1; each step identifies problems with Perl syntax constructs or operators that may need some sort of code remediation.

Step 1. Inspect Solaris-specific module dependency

The first step is all about inspecting imported Perl modules. Some of them are specifically built for Solaris, and once you enable them, they will tie the script to the Solaris platform. We need to identify these modules by the script code, figure out their leveraged functions and variables, and make the proper changes so they don't tie you to a platform where your Perl script isn't running.

You can find a comprehensive list of Solaris-specific modules on the CPAN repository; they usually have names starting with either Solaris:: or Sun::Solaris::.

You can use the shell script in Listing 1 can be used to identify Perl script files with import statements that start with "Solaris" or "Sun."

Listing 1. How to find Solaris module imports
find . -name "*.pl" -exec grep -ilP "^\s*use (Solaris|Sun)" {} \;

You can modify the code in Listing 1 to make that script more accurate in finding Solaris-specific modules within Perl scripts. For example, you can convert the shell script in Listing 1 to Perl and thus leverage the PPI module for parsing. The use of that module is beyond the scope of this article, but we recommend it for greater precision when parsing Perl codes.

After identifying scripts with Solaris-specific code, you need to search for equivalent modules that work on Linux as well. It's not always easy to identify such modules in terms of functionality since the original modules might deal with technologies exclusive to the Solaris platform. When that occurs, you will have to perform a deeper analysis.

To use an equivalent Linux-based module, you need to replace all import statements as well as any called functions and variables with the equivalents of the new module.

Step 2. Inspect calls to Solaris-specific system commands

Calling operating system commands from within the Perl script can present the most common problem when performing Solaris to Linux migrations for several reasons:

  • Lack of commands on the target system
  • Commands with different set of flags
  • Commands that behave differently on both platforms

Therefore, you need to take special care when dealing with this issue, the class number 02 portability issue: System calls.

The goal here is to ensure that any system command evoked on the script syntactically and semantically works properly on Linux as well. In short, it's all about identifying Perl core functions and operators leveraged in the script that carries Solaris-specific system commands.

Let's start with an example. Listing 2 shows a simple Perl script used to display the memory size of a Solaris system.

Listing 2. Perl script to display system memory size
my $mem_info = `prtconf | grep Memory`; 
my (undef, $mem_size) = split(':', $mem_info); 
($mem_size, undef) = split(' ', $mem_size); 
print "Memory size is: ".$mem_size."\n";

Now let's suppose we want to run the same script on Linux. We figure out that it calls a piped system command (prtconf | grep Memory) through the backtick operator, and the prtconf command is specific to Solaris. The first step is to find a replacement for it.

You may use cat /proc/meminfo | grep MemTotal even though the output is formatted differently since the /proc/meminfo hold size information in KBs and prtconf is in MBs.

To remediate this script, you can replace ptrconf with cat /proc/meminfo, but to keep the output information in MBs (we don't know if the output of this script is used as input in other scripts, so it's critical to not change it), we can use a simple conversion. Listing 3 shows an example of how this script could be remediated.

Listing 3. Remediating the Listing 2 script
my $mem_info = `cat /proc/meminfo | grep MemTotal`; 
my (undef, $mem_size) = split(':', $mem_info); 
($mem_size, undef) = split(' ', $mem_size); 
$mem_size = int($mem_size / 1000); 
print "Memory size is: ".$mem_size."\n";

Because Perl is flexible enough to accommodate different ways of executing operating system commands, there are many different core functions and operators used for that purpose. Table 2 lists Perl core functions and operators leveraged to call system commands from within a Perl script.

Table 2. Core functions and operators leveraged to call system commands
Function/operatorExample in SolarisExample in Linux
backtick (``)`prstat``ps -e`
execexec("/usr/sbin/df -kZ")exec("/bin/df -kZ")
openopen DATA, "cat /var/cron/log |"Open DATA, "cat /var/log/cron"
readpipereadpipe( "cat /etc/default/login " )Readpipe( "cat /etc/default/login" )

You can check Perl documents for further information about each of these functions and operators, as well as any others that are not part of Perl's core language. Consult the IBM Redbook "Solaris to Linux Migration: A guide for system administrators" to learn more about differences in system administration commands.

Step 3. Inspect use of OS pathnames

Now let's discuss migrating leveraged pathnames by the Perl script; this step is similar to Step 2. Here you need to pay attention to syntax elements and operators that are used to open or manipulate files. Although there are specific operators to do that, some problems with referenced pathnames may arise. (You can also see this when you invoke system command like those mentioned in Step 2.)

Listing 4 shows a small script that reads the NFS server config file of Solaris and prints it to standard output.

Listing 4. Perl script that prints the contents of a system file to standard output
open(NFSCONF, '/etc/default/nfs'); 
print <NFSCONF>; 

When migrating from Solaris to Linux, you need to pay attention to system paths, which often differ. In this example, the file /etc/default/nfs referenced on this Solaris script doesn't exist on the Linux/Red Hat distribution, but it is replaceable with /etc/sysconfig/nfs. Listing 5 shows the script after it's remediated.

Listing 5. Remediation of Listing 4
open(NFSCONF, '/etc/sysconfig/nfs'); 
print <NFSCONF>; 

You need to be aware of any Perl commands that manipulate files. Table 3 shows some common path-handling commands used in Perl; if any of those are being used in a script, you'll need to remediate pathnames when migrating.

Table 3. Common path-handling commands in Perl
chdirChanges the working directory.
chmodChanges the permission of a list of files.
globReturns a (possibly empty) list of filename expansions.
linkCreates a new filename linked to the old filename.
mkdirCreates a new directory.
openOpens a file.
opendirOpens a directory.
renameChanges the name of a file.
rmdirDeletes a specified directory.
sysopenOpens a specified file and associates it with a specified file handle.

Step 4. Inspect use of special variables that hold Solaris-specific information

Some special variables hold information on the environment that may be specific to Solaris; you need to identify these variables and make the proper translations. Table 4 lists a few core variables that may hold Solaris-specific information or references.

Table 4. Some Perl core variables; see all atPerl Programming Documentation
ENVContains current environment variables. Some of these variables may not support direct mapping between Solaris and Linux. Some examples are the variables NETPATH, MSGVERB, and SEV_LEVEL.
SIGContains signal handlers for signals. See the Related topics section for more information about differences in signaling on both platforms.

Step 5. Identify use of functions that are implemented differently across platforms

Some core Perl functions are either not implemented or have been implemented differently on various platforms; these functions will behave differently on Solaris and Linux. You will need to change them so they cooperate or find the complementary version for the Linux platform and segue into that one; again, see Perl Programming Documentation (see Related topics for a link).


Identifying the five most common components of Perl scripts that can cause trouble when migrating from Solaris to Linux (or HP/UX or AIX to Linux) is not terribly hard. But doing the necessary code remediations and code substitutions to successfully bring your scripts to Linux can be time consuming, especially if you have many scripts to migrate. The advice and examples for code remediations in this article should help you get started. Good luck!

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=Linux, Open source
ArticleTitle=Port Perl scripts from Solaris to Linux