Month: June 2012

Character Classes or Character Sets

http://www.regular-expressions.info/charclass.html

 

Note that the only special characters or metacharacters inside a character class are the closing bracket (]), the backslash (\), the caret (^) and the hyphen (-). The usual metacharacters are normal characters inside a character class, and do not need to be escaped by a backslash. To search for a star or plus, use [+*]. Your regex will work fine if you escape the regular metacharacters inside a character class, but doing so significantly reduces readability.

get the result from commands executed in expect

http://www.perlmonks.org/?node_id=58634

If you have ever used Expect to execute commands on a remote system I am sure you have run into the problem of parsing the command output from the output of the Expect methods exp_before(), clear_accum(), etc… . If you send your command to this subroutine it will parse the output for you and return the command output as it would be returned from a backtick execution. Note: This subroutine uses a global Expect object variable which already has an established connection. The subroutine will not take commands that end in & .. for those commands just use $expect->print method.

# Executes a command via a global expect object and
# returns the output of the command.
#
# Arguments:
#       1 – Command     <string variable containing the command string
+>
# Returns:
#       String variable cotaining the output of the specified command.
#

sub expect_execute($) {
$expect->clear_accum();
my $command = shift;
my $x = ”;
my $temp = ”;
if ( $command =~ /;$/ ) {
chop( $command );
}
print $expect “$command | sed ‘s/^/COMMAND_OUT: /g’; echo -n E
+ND_; echo EXPECT\n”;
$expect->expect( 300, -re => ‘^END_EXPECT’ );
my $result = $expect->exp_before();
( my @result ) = split( /\n/, $result );
$result = ”;
foreach $x ( @result ) {
$temp = $x;
if ( chop( $temp ) eq “\r” ) {
chop( $x );
}
if ( $x =~ m/^COMMAND_OUT: / ) {
$temp = substr( $x, 13 );
$result = $result . $temp . “\n”;
}
}
return $result;
}

What the hell is Perl is?

Perl or Practical Extraction and Report Language is described by Larry Wall, Perl’s author, as follows: “Perl is an interpreted language optimized for scanning arbitrary text files, extracting information from those text files, and printing reports based on that information. It’s also a good language for any system management tasks. The language is intended to be practical (easy to use, efficient, complete) rather than beautiful (tiny, elegant, minimal).”

In Unix, how do I use the scp command to securely transfer files between two computers?

Unlike rcp or FTP, scpencrypts both the file and any passwords exchanged so that anyone snooping on the network can’t view them.

Warning: Be careful when copying between hosts files that have the same names; you may accidently overwrite them.

The syntax for the scp command is:

scp [options] [[user@]host1:]filename1 … [[user@]host2:]filename2

[[user@]host1:]filename1 is the source file and path, and [[user@]host2:]filename2 is the destination.

For example, if user dvader is on a computer called empire.gov, and wants to copy a file called file1.txt to a directory called somedir in his account on a computer called deathstar.com, he would enter:

scp file1.txt dvader@deathstar.com:somedir

Likewise, if he wanted to copy the entire contents of the somedir directory on deathstar.com back to his empire.gov account, he would enter:

scp -r dvader@deathstar.com:somedir somedir

Similarly, if he is working on another computer, but wanted to copy a file called file1.txt from his home directory on empire.gov to a directory called somedir in his account on deathstar.com, he would enter:

scp dvader@empire.gov:file1.txt dvader@deathstar.com:somedir When using wildcards (e.g.,  *  and  ? ) to copy multiple files from a remote system, be sure to enclose the filenames in quotes. This is because the Unix shell, not the scp command, expands unquoted wildcards

executing external commands in Perl

There are many ways to execute external commands from Perl. The most commons are:

  • system function
  • exec function
  • backticks (“) operator
  • open function

All of these methods have different behaviour, so you should choose which one to use depending of your particular need. In brief, these are the recommendations:

method use if …
system() you want to execute a command and don’t want to capture its output
exec you don’t want to return to the calling perl script
backticks you want to capture the output of the command
open you want to pipe the command (as input or output) to your script

More detailed explanations of each method follows:

 

  • Using system()

 

system() executes the command specified. It doesn’t capture the output of the command.

system() accepts as argument either a scalar or an array. If the argument is a scalar, system() uses a shell to execute the command (“/bin/sh -c command”); if the argument is an array it executes the command directly, considering the first element of the array as the command name and the remaining array elements as arguments to the command to be executed.

For that reason, it’s highly recommended for efficiency and safety reasons (specially if you’re running a cgi script) that you use an array to pass arguments to system()

Example:

#-- calling 'command' with arguments
system("command arg1 arg2 arg3");

#-- better way of calling the same command
system("command", "arg1", "arg2", "arg3");

The return value is set in $?; this value is the exit status of the command as returned by the ‘wait’ call; to get the real exit status of the command you have to shift right by 8 the value of $? ($? >> 8).

If the value of $? is -1, then the command failed to execute, in that case you may check the value of $! for the reason of the failure.

Example:

system("command", "arg1");
if ( $? == -1 )
{
print "command failed: $!\n";
}
else
{
printf "command exited with value %d", $? >> 8;
}

 

  • Using exec()

 

The exec() function executes the command specified and never returns to the calling program, except in the case of failure because the specified command does not exist AND the exec argument is an array.

Like in system(), is recommended to pass the arguments of the functions as an array.

 

  • Using backticks (“)

 

In this case the command to be executed is surrounded by backticks. The command is executed and the output of the command is returned to the calling script.

In scalar context it returns a single (possibly multiline) string, in list context it returns a list of lines or an empty list if the command failed.

The exit status of the executed command is stored in $? (see system() above for details).

Example:

#-- scalar context
$result = `command arg1 arg2`;

#-- the same command in list context
@result = `command arg2 arg2`;

Notice that the only output captured is STDOUT, to collect messages sent to STDERR you should redirect STDERR to STDOUT

Example:

#-- capture STDERR as well as STDOUT
$result = `command 2>&1`;

 

  • Using open()

 http://www.perlhowto.com/executing_external_commands

Use open() when you want to:

– capture the data of a command (syntax: open(“command |”))

– feed an external command with data generated from the Perl script (syntax: open(“| command”))

Examples:

#-- list the processes running on your system
open(PS,"ps -e -o pid,stime,args |") || die "Failed: $!\n";
while ( <PS> )
{
#-- do something here
}

#-- send an email to user@localhost
open(MAIL, "| /bin/mailx -s test user\@localhost ") || die "mailx failed: $!\n";
print MAIL "This is a test message";

 

*****************************************************

There are several ways to invoke a programm. One of the main differences is in the returning value.

  • system("wc -l");
    Will call the given command and return the return value of that command. This is usually not what you want, because most of the times wc -l will mean that you want to get the number of lines back from that call and not if that call was successful or not.
  • $nol = `wc -l`
    The backticks call the command and return it’s output into the variable (here $nol. In this case this will be what you want.
  • Another way of doing this is to use
    $nol = qx/wc -l/;
    (mnemonic: qx quote execute). I think is just the same as the backquotes (at least I don’t know any difference)
  • Of course there are other ways (exec,fork) that behave different with respect to processes, but I don’t know much about this

Hope this helps…