Enable thread support for Perl in Windows? - multithreading

I'm trying utilize threads in my Perl script, running on Windows 7. I'm unable to compile the script as Perl wasn't built with thread support when initially installed (the previous user installed Perl without thread support).
How can I rebuild Perl with thread support?
Thanks.

Most people use ActivePerl or Strawberry Perl on Windows, both of which have thread support enabled.
That said, I find it very odd that you have a Perl without thread support on Windows. I think you could be mistaken. You can check if your Perl has thread support by using
>perl -v | find "built for"
... for MSWin32-x86-multi-thread-64int
or more directly with
>perl -V:usethreads
usethreads='define';

First check whether multithreading is supported by your perl or not :
#!/usr/bin/perl
use Config;
$Config{useithreads} or die('This perl interpreter does not support execution threads.');
print "This perl interpreter supports multithreading\n";

Related

Keep perl script running after ssh disconnect

Is there a native way to keep a perl script running on a server(uninterrupted by ssh disconnections) without the use of tools like tmux and screen ? I am using Ubuntu.
You can try the POSIX command nohup
Most shells also come with disown
As far as a perl native solution, you can simply use the signal handling features of perl.
$SIG{HUP} = sub {
print "got SIGHUP\n";
};
screen is what you are looking for.

Multiple GNU-Bash commands behave differently when run on aix, any solutions

I have written a bash script on linux, and it works well, as a part of migration I moved [rather added] an aix 7.2 node to my cluster. When I tried running bash scripts on aix it failed with multiple errors on different gnu bash commands.
[ps: I have installed gnu bash on this aix node, IBM calls it a toolbox made for aix, which contains a collection of open source and GNU software built for AIX IBM Systems]
For example :
- grep -oP isn't supported
- ls -h doesn't work
- getopts fails to get parameter passed and $# as well.
I am not sure if I am doing it right with just installing the gnu bash on aix. Have anyone had any experience porting bash scripts over to ssh?
Are there any pointer community can suggest to get bash script work on aix?
The issue is that these commands are not part of bash. What you need is the GNU versions of all these utilities, that is grep and ls. As for getopts builtin, please check which version of bash you developed the script against as compared to which version you're running it against:
$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
That's my bash version. If your production environment has a really old version of bash, you'll need to use bourne shell scripting, instead of bash scripting (Bourne Again SHell) to ensure portable scripts.
Edit: Plagarizing from Olivier Dulac's answer, please take a look at the POSIX page on shell command language for portable Bourne shell scripting. Do take a look at the POSIX standard page for ls and grep for portable options.
Another Edit: See the page on AIX Toolbox for Linux for GNU variants of the standard utilities, which are installed into /usr/linux/bin
Yet another Edit: According to pedz, this link shows better (100% compatible) replacements for the AIX Toolbox
stick to standards, as much as possible...
write sh-compatible scripts, if you need to use them on various systems.
Stick to ancient options that are widely suppotred (-h option for ls, and other gnu introduced niceties, are nice to have, but NOT portable enough)

perl library path

I need to retrieve the path where the perl libraries Statistics and Distributions are located. The path is necessary to run the script. I'm on a computer cluster. Can anyone help me?
Thanks
This answer assumes that the module is in fact installed, but not in a place that perl is looking for.
Generally, the Perl module Statistics::Distributions will be contained in a file called Statistics/Distributions.pm. On Linux and similar systems, one can search for these files quickly with the locate command:
locate Statistics/Distributions.pm
If it is installed, locate will spit out a line similar to
/opt/my_perl/lib/Statistics/Distributions.pm
You can then instruct the perl interpreter to look in this path, too, in various ways. One is to define the environment variable PERL5LIB, i.e. from bash:
prompt> PERL5LIB=/opt/my_perl/lib/ ./myscript.pl
Or you can use the perl -I switch:
prompt> perl -I/opt/my_perl/lib/ ./myscript.pl
Or you can modify the script to use lib; there is more than one way to do it ;-)
perldoc -m Your::Module - displays source of module
perldoc -l Your::Module - display path to library if it's installed and found in PERL5LIB, -I, #INC, etc.
If you mean you need the path of a module you're using in a program, that's stored in %INC:
$ perl -MLWP::Simple -le 'print $INC{"LWP/Simple.pm"}'
/usr/share/perl5/LWP/Simple.pm
"Can't locate XXX in #INC" usually indicates the module isn't installed. Have you installed Statistics::Distributions?
cpan Statistics::Distributions
I had the same trouble and it can be fixed both ways:
1) by running the command
perl -I/blabla/folder_your_module_is_installed/blib/lib/ ./script.pl
for dummies like me, it is important to note that the end of the path is lib/, not lib/Other_folder/. Because there are more folders after it.
2) inside the script you can write:
use lib 'blabla/folder_your_module_is_installed/blib/lib/';
save and run perl scripit.pl

What is the proper way to make a bash script portable between Linux and FreeBSD?

I am working on some bash scripts that I'd like to work across my Linux and FreeBSD systems.
Since I mostly work in Linux, I am used to starting my bash scripts with
#!/bin/bash
But this doesn't work on FreeBSD since bash lives at /usr/local/bin/bash. So on FreeBSD my scripts need to start with
#!/usr/local/bin/bash
So is there something else I could use that would be portable across both systems? I'd rather not maintain two versions of the scripts.
#!/usr/bin/env bash
should do the trick, provided that bash is on the path somewhere. See here for more details.
Honestly, if you want portability, invoke as /bin/sh and code to POSIX. It's less pretty, but you will run into fewer potential issues if you do.
Use #!/bin/sh on both systems if you want to be portable and avoid bashisms entirely.

How to overcome an incompatibility between the ksh on Linux vs. that installed on AIX/Solaris/HPUX?

I am involved in the process of porting a system containing several hundreds of ksh scripts from AIX, Solaris and HPUX to Linux. I have come across the following difference in the way ksh behaves on the two systems:
#!/bin/ksh
flag=false
echo "a\nb" | while read x
do
flag=true
done
echo "flag = ${flag}"
exit 0
On AIX, Solaris and HPUX the output is "flag = true" on Linux the output is "flag = false".
My questions are:
Is there an environment variable that I can set to get Linux's ksh to behave like the
other Os's'? Failing that:
Is there an option on Linux's ksh to get the required behavior? Failing that:
Is there a ksh implementation available for Linux with the desired behavior?
Other notes:
On AIX, Solaris and HPUX ksh is a variant of ksh88.
On Linux, ksh is the public domain ksh (pdksh)
On AIX, Solaris and HPUX dtksh and ksh93 (where I have them installed) are consistent with ksh
The Windows NT systems I have access to: Cygwin and MKS NT, are consistent with Linux.
On AIX, Solaris and Linux, bash is consistent, giving the incorrect (from my perspective) result of "flag = false".
The following table summarizes the systems the problem:
uname -s uname -r which ksh ksh version flag =
======== ======== ========= =========== ======
Linux 2.6.9-55.0.0.0.2.ELsmp /bin/ksh PD KSH v5.2.14 99/07/13.2 false
AIX 3 /bin/ksh Version M-11/16/88f true // AIX 5.3
/bin/ksh93 Version M-12/28/93e true
SunOS 5.8, 5.9 and 5.10 /bin/ksh Version M-11/16/88i true
/usr/dt/bin/dtksh Version M-12/28/93d true
HP-UX B.11.11 and B.11.23 /bin/ksh Version 11/16/88 true
/usr/dt/bin/dtksh Version M-12/28/93d true
CYGWIN_NT-5.1 1.5.25(0.156/4/2) /bin/ksh PD KSH v5.2.14 99/07/13.2 false
Windows_NT 5 .../mksnt/ksh.exe Version 8.7.0 build 1859... false // MKS
Update
After some advice from people in my company we decided to make the following modification to the code. This gives us the same result whether using the "real" ksh's (ksh88, ksh93) or any of the ksh clones (pdksh, MSK ksh). This also works correctly with bash.
#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
flag=true
done < junk
echo "flag = ${flag}"
exit 0
Thanks to jj33 for the previously accepted answer.
Instead of using pdksh on linux, use the "real" ksh from kornshell.org. pdksh is a blind re-implementation of ksh. kornshell.org is the original korn shell dating back 25 years or so (the one written by David Korn). AIX and Solaris use versions of the original ksh, so the kornshell.org version is usually feature- and bug- complete. Having cut my teeth with SunOS/Solaris, installing kornshell.org ksh is usually one of the first things I do on a new Linux box...
After some advice from people in my company we decided to make the following modification to the code. This gives us the same result whether using the "real" ksh's (ksh88, ksh93) or any of the ksh clones (pdksh, MSK ksh). This also works correctly with bash.
#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
flag=true
done < junk
echo "flag = ${flag}"
exit 0
Thanks to jj33 for the previous accepted answer.
I installed 'ksh' and 'pdksh' on my local Ubuntu Hardy system.
ii ksh 93s+20071105-1 The real, AT&T version of the Korn shell
ii pdksh 5.2.14-21ubunt A public domain version of the Korn shell
ksh has the "correct" behavior that you're expecting while pdksh does not. You might check your local Linux distribution's software repository for a "real" ksh, instead of using pdksh. The "Real Unix" OS's are going to install the AT&T version of Korn shell, rather than pdksh, by default, what with them being based off AT&T Unix (System V) :-).
Do you have to stay within ksh?
Even if you use the same ksh you'll still call all kinds of external commands (grep, ps, cat, etc...) part of them will have different parameters and different output from system to system. Either you'll have to take in account those differences or use the GNU version of each one of them to make things the same.
The Perl programming language originally was designed exactly to overcome this problem.
It includes all the features a unix shell programmer would want from he shell program but
it is the same on every Unix system. You might not have the latest version on all those
systems, but if you need to install something, maybe it is better to install perl.
The reason for the differences is whether the inside block is executed in the original shell context or in a subshell. You may be able to control this with the () and {} grouping commands. Using a temporary file, as you do in your update, will work most of the time but will run into problems if the script is run twice rapidly, or if it executes without clearing the file, etc.
#!/bin/ksh
flag=false
echo "a\nb" | { while read x
do
flag=true
done }
echo "flag = ${flag}"
exit 0
That may help with the problem you were getting on the Linux ksh. If you use parentheses instead of braces, you'll get the Linux behavior on the other ksh implementations.
Here is the another solution for echo "\n" issue
Steps:
Find ksh package name
$ rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep "ksh"
ksh-20100621-19.el6_4.3(x86_64)
uninstall ksh
$ sudo yum remove ksh-20100621-19.el6_4.3.x86_64
down load pdksh-5.2.14-37.el5_8.1.x86_64.rpm (Please check OS for 32-bit or 64-bit and choose correct pkg)
Install pdksh-5.2.14-37.el5_8.1.x86_64.rpm
$ sudo yum -y install /SCRIPT_PATH/pdksh-5.2.14-37.el5_8.1.x86_64.rpm
Output before PDKSH install
$ ora_db_start_stop.sh
\n==============
Usage: START
==============\n\n
./ora_db_start_stop.sh START ALL \n
OR \n
./ora_db_start_stop.sh START ONE_OR_MORE \n
\n==============
Usage: STOP
==============\n\n
./ora_db_start_stop.sh STOP ALL \n
OR \n
./ora_db_start_stop.sh STOP ONE_OR_MORE \n\n
After PDKSH install
==============
Usage: START
./ora_db_start_stop.sh START ALL
OR
./ora_db_start_stop.sh START ONE_OR_MORE
==============
Usage: STOP
./ora_db_start_stop.sh STOP ALL
OR
./ora_db_start_stop.sh STOP ONE_OR_MORE
I don't know of any particular option to force ksh to be compatible with a particular older version. That said, perhaps you could install a very old version of ksh on your linux box, and have it behave in a compatible manner?
It might be easier to install a more modern version of amy shell on the AIX/HP-UX boxes, and just migrate your scripts to use sh. I know there are versions of bash available for all platforms.
Your script gives the correct (true) output when zsh is used with the emulate -L ksh option. If all else fails you may wish to try using zsh on Linux.

Resources