How to exit current CPAN module and open a new session? - perl

I am new to perl and CPAN. I see that perl is installed in my system.
However, I would like to install DBI package to run a script called INSTALL.PL.
When I type CPAN, I get the below error message
Loading internal null logger. Install Log::Log4perl for logging messages
Terminal does not support AddHistory.
There seems to be running another CPAN process (pid 3986). Contacting...
Other job not responding. Shall I overwrite the lockfile '/home/abcd/.cpan/.lock'? (Y/n) [y]
If I give no, I don't get the CPAN command prompt. Whereas if I give yes, I get the below command prompt
nolockcpan[1]
May I know what does the error message mean and what are the steps to follow to avoid this message again?
Can't I enter into cpan mode and press CTRL+Z exit and again get into cpan mode?
How can I avoid this error message and when can this happen?

It means that cpan wasn't properly exited the last time it was run. This could happen if you close your terminal while it's still running, for example.
You can use exit or quit to exit cpan. It will also exit when its STDIN reaches EOF (which can be done using Ctrl-D on unix).
You talk of Ctrl-Z, which stops (suspends) it, but doesn't exit it. Use fg to return to cpan after stopping it. That said, launching cpan while it's stopped or otherwise still running results in a different message (Other job is running. Shall I try to run in downgraded mode?).

Related

Perl script file run manually but not in crontab

I have a perlscript file was running fine in crontab but suddenly it stopped running without any modification.
cd /home/user/public_html/crons && ./script.pl 2>&1 >/dev/null
The top of the script file is #!/usr/bin/perl -X
The output expect from this script is changes in database
I have another script file with the same modification and still works fine
When I run the file in the browser it works fine and execute all lines without any problem
I tried full path /usr/bin/perl but it didn't work
I tried Perl at the beginning but it didn't work
I run the command from SSH using putty but nothing happened
I checked log file /var/log/cron but no errors at all
I created temporary log file cd /home/user/public_html/crons/script.pl> /tmp/temp.log 2>&1 to see the errors but the log is empty
Here is the solution:-
I found the issue, There is was a stuck process for the same cron file , so i killed this process and its fixed
You can find your file process like this
ps aux | grep 'your cron file here'
This is a really common antipattern people seem to tend toward with cron.
Cron sends you an email with the output of your script, if it generates any output. People often redirect output to /dev/null to prevent cron from sending the email. This is bad because now the output of your script is lost entirely. Even if the script has some built-in logging, it might generate errors before it gets the log file opened and those are lost. It also might crash in a way that doesn't get written to the logging mechanism.
At a bare minimum, you should just remove 2>&1 >/dev/null to start receiving the email. (and also, test your mail setup using a temporary cron job like 1 * * * * echo "Test" )
The next better solution is to change it to >> /var/log/myscript/current.log and then also set up something to rotate the log files (like logrotate) and also make sure to create that directory with permissions that the script user is allowed to write to it. By only redirecting STDOUT of the script, any errors or warnings it writes to STDERR cause you to get an email, and if there are no errors/warnings the output goes to the log file and no email gets sent.
Neither of those changes solve the root problem though, which is that when cron runs your script it does so with a different environment than you have on the command line. What you really want is a way to run the script with a consistent environment, and log it. The "ultimate solution" is to define your task in some kind of service manager, and then use cron to occasionally start it. For instance, you could use systemd and define a service that doesn't restart, then use systemctl start my_custom.service in your cron job. Now you can test independent of cron, and your tests will have the same exact environment, and be logged by the service manager. As extra bonuses, you are protected from accidentally running your script twice at once, and you get a clean way to stop a running cron job without the danger of stale pid files.
I don't particularly advocate systemd myself, but thankfully there are lots of alternatives:
Runit : http://smarden.org/runit/runsvdir.8.html
S6 : https://skarnet.org/software/s6/
Perp : http://b0llix.net/perp/site.cgi?page=perpd.8
(but installing and configuring a service manager is a bigger task than just using systemd if your distro is based on systemd) Each of these allows you to define a service that doesn't restart. Then you use a shell command to issue a "run once" directive to the supervisor, which runs the task as a child. Now you can easily launch the jobs yourself and see all the errors in the log, and then add that command to the crontab and know that it will run identically when cron starts it.
Back to your original problem, once you get some logging you are likely to discover it is a permission problem or a upgraded module in the system perl.

How can you invoke interactive Perl debugging with hypnotoad or morbo?

I'm new to mojolicious but have been using Perl for some time. I have to jump through some hoops but I can get the interactive Perl debugger (and Komodo) working with remote connections for Apache but I can't find anything about interactive debugging with hypnotoad or morbo.
The command line examples in the basic tutorial on http://mojolicio.us/perldoc/Mojolicious/Guides/Tutorial#Hello-World work fine because you can launch them with perl -d, but I don't see anyway to tell the hypnotoadctl script to put the service in interactive debug mode ala apache.
Is this not possible? Hints? Tips? Pointers?
morbo and hypnotoad are perl programs, so you can launch them with the -d switch.
perl -d $(which morbo) myMojoApp.pl
It's probably easiest to sprinkle a bunch of $DB::single = 1 statements around you app where you want your initial breakpoints to go and run c as the first debugger command. When you run a request that hits a breakpoint, you'll get a debugger prompt in the terminal that launched morbo.
hypnotoad will be trickier to use with the debugger because it quickly closes all the standard filehandles, calls fork several times, and becomes a daemon.
As JHThorsen points out, standard Mojolicious tests are actually ordinary Perl scripts, so you can debug your tests with:
perl -d t/mytest.t
The -Ilib adds the lib/ directory to the #INC include list so your modules will be loaded.
One catch is that many modules are not loaded until execution time, so if the debugger hassles you about symbols that aren't loaded yet, you'll probably want to set breakpoints after forcing a debug prompt with a carefully inserted
$DB::single = 1;
Thanks to 'pink_mist'. You can do:
perl -d myMojoApp.pl daemon -l http://*:29849
But application config is not applyied. I do not know why.

System call to run pbmtextps: ghostscript

I'm coding a Perl script to generate images with text in them. I'm on a Linux machine. I'm using pbmtextps. When I try to run pbmtextps in Perl with a system call like this
system("pbmtextps -fontsize 24 SampleText > out.pbm");
I get this error message
pbmtextps: failed to run Ghostscript process: rc=-1
However, if I run the exact same pbmtextps command from the command-line outside of Perl, it runs with no errors.
Why does it cause the ghostscript error when I run it from inside a Perl script?
ADDITIONAL INFO: I tried to hack around this by creating a C code called mypbmtextps.c which does the exact same thing with a C system call. That works from the command line. No errors. But then when I call that C program from the Perl script, I get the same ghostscript error.
ANSWER: I solved it. The problem was this line in the PERL script:
$SIG{CHLD} = 'IGNORE';
When I got rid of that (which I need for other things, but not in this script) it worked okay. If anyone knows why that would cause a problem, please add that explanation.
Ah-ha. Well, the SIGCHLD is required for wait(), and so required for perl to be able to retrieve the exit status of the child process created by system(). In particular, system() always returns -1 when SIGCHLD is ignored. $? will also be unavailable with SIGCHLD blocked.
What printed the error message? pbmtextps, or your perl script?
As far as I know, the signal handler for your perl process shouldn't affect the signal handler for the child processes, but this could depend on your version of perl and your OS version. On my Linux Mint 13 with Perl 5.14.2 the inner perl script prints 0, with the outer script printing -1:
perl -e '$SIG{CHLD}= "IGNORE"; print system(q{perl -e "print system(q(/bin/sleep 1))"})'
Is your perl script modifying the environment?
You can test with
system("env > /tmp/env.perl");
and then compare it to the environment form your shell:
env > /tmp/env.shell
diff /tmp/env.shell /tmp/env.perl
Is the perl script also being run from the shell, or is it being run from some other process like cron or apache? (in particular, you should check $PATH)

ActivePerl and PPM

I have installed ActivePerl 5.14.2 on a Windows 32 bit machine running XP. My problem is that I'm trying to install a few modules with PPM and it's not working out.
According to ActiveState's website, all you need to do to install a module from their repository is "ppm install module name" , example: http://code.activestate.com/ppm/Template-Toolkit/
Every time I try this or any other module I get: "No Perl script found in input"
Even when I do just "ppm" I get the same message, even though the GUI should run.
When I run PPM with a GUI from the start menu I get this error: "Failed 500 Can't connect to ppm4.activestate.com:8080 (connect: timeout)”
I though that it might be my connection, so using cmd.exe I used the set HTTP_PROXY command and then tried ppm install, but still no luck. So is there any way I can get these modules installed?
Any advice is appreciated !!
Invoke the cpan prompt from your command prompt. Go to cmd and simply type cpan. If you successfully enter cpan prompt them there is probably no issues with your Perl installation. To install a module from cpan prompt just use
cpan>install Module::Name
Screenshot below shows command to install module Net::Stomp
If the above does not work, check if your FTP data and connection ports needs to be added to the Windows firewall exceptions (Ports 20 (FTP Command port) and 21 (FTP Data port)).
Alternatively (if you don't want to add port 20 21 to exception), you can go to the cpan prompt and use an ftp_proxy by
cpan> o conf ftp_proxy http://your.ftpproxy.com
and then issue install command. Or you can update your ../CPAN/config.pm file to make permanent changes to the ftp_proxy parameter.
The next step would be to try set the FTP_PASSIVE mode to 1. By default the libnetcfg configuration for this is set to 0. To change this find libnetcfg.bat file (should be somewhere C:\Perl\bin), open the file in an editor and replace
ftp_int_passive 0
to
ftp_int_passive 1
Again, looking at you r timeout error it seems that your network is blocking you from accessing the CPAN ftp mirrors, this would happen mostly if you are inside a corporate VPN. The solution to this can only be proxy servers.

perl debugger freezes

First time perl user and I am trying to debug some script to follow project logic and of course syntax.
Using cygwin after entering at command line $
$ perl -d sample.pl
Loading DB routines from perl5db.pl version 1.3
Editor support available.
Enter h or `h h' for help, or `perldoc perldebug' for more help.
main::(sample.pl:5): print 'Hello world.'; # Print a message
DB<1>
It hangs at the DB<1> line. I cannot enter anything at the prompt.
Is there a reason why this post is inappropriate? or how is this not clear?
This is the actual program code:
#!/usr/local/bin/perl
#
# Program to do the obvious
#
print 'Hello world.'; # Print a message
I upgraded my cygwin installation at home and ran into a similar problem (though maybe not the exact same problem -- the perl debugger still responds to my input but does not display my input, and fubars my input even after I quit the debugger). In the meantime while I figure what is going on, my workaround is to fire up xemacs, launch a shell (M-x shell), and run the perl debugger from the emacs buffer.
If this works for you, then there is something funky going on with your cygwin terminal settings. If your debugger hangs even in an emacs buffer, then something else funky is going on but I have no idea what it could be.
Sorry for reviving this three-year-old question, but I believe to have been hit with the same problem, and to have found the solution.
In my case, perl -de0 invokes infocmp from ncurses, which hangs in a weird way (can't kill it). And infocmp seemed to be a victim of my Avast anti-virus which is listed under BLODA as affecting Cygwin. Disabling it resolved the issue -- see if you have any of the listed applications and try disabling it (perhaps also try safe mode).
Also, simply renaming infocmp.exe allowed perl -d to run normally. In the end I used this approach and left my Avast running.
It could also be a different executable that perl -d is starting -- try to run whatever hangs with strace, see what is the last executable mentioned and try to see if that is the culprit.