Remove script itself - perl

I would like my script to remove itself automatically since its work is done. I have added the line below to the end of my script:
unlink($0);
For some reasons, it's not working. Could you please advise what I should do? Probably, there is another approach or I could add an error message to find out why it's not removed?
Thank you.

I don't know why you can't. It works in my machine. Maybe your file system locks the file when it's running.
And you please try this:
exec "rm -f '$0'";
which replace the current Perl process with the rm one. This should release your script and has it removed.

at the end of your script:
system("sh -c 'sleep 1; rm -f $0' &");
Bit hacky, but why do you need to delete your script? Surely that means something has created it, why not have the creator delete it too?

You can't do that. Your script is still running so the file will be in use, that's why it can't delete itself.
You need to call an external script to delete the first script after it has died.

Related

ant: command not found

I am having some trouble running ant. Here is a simplified verison of my problem. I have a shell script script1.sh:
export ANT_HOME=/opt/Ant
ant -version
This works. but when I try create another script script2:
cd /location/of/script1
sudo -E ./script1.sh | tee log.txt
I get the error ant: command not found. Does anyone know why this is happening.
Sounds like you're losing your PATH setting after sudo. Try adding echo $PATH in script1.sh to see the before and after values. Or just define script1.sh as
export ANT_HOME=/opt/Ant
${ANT_HOME}/ant -version
Without knowing what shell, or seeing more of the scripts it's hard to tell exactly what is happening. But if you want script2 to know about ANT_HOME you're probably going to need to source or eval script1. See here. Also I know pipes '|' cause Bash to perform operations within sub-shells which can be problematic under certain circumstances (if you're using Bash).
EDIT:
Double check that you are using the version of ant that you think you are:
#!/bin/bash
# Capital A here seems suspicious to me...
export ANT_HOME=/opt/Ant
echo "`${ANT_HOME}/ant -version`"

How to stop the execution of .sh script at certain time?

I have the following script which ensure that a .php file will be invoked every 3 seconds.
#!/bin/bash
for (( i=0; i<43200; i++ ))
do
/usr/bin/php /var/www/vhosts/mydomain.com/httpdocs/somefile.php
sleep 3
done
I would like to be able to stop the script excecution if the time is 23:58:59
Anyone can help me?
Thanks, Zoran
case `date +%H%M` in 2359) break ;; esac
Edit: I discovered the zero padding in the date formatting string was not portable, so I took it out. It's not useful or necessary in this case anyway.
AGAIN me.
since your script has no imput youmcan try to launch yor script in the following way:
./yourscript.sh & sleep 10 && kill %1 && fg
give it a try.
Se
I think there is no direct way without using a scripting language like python or perl.
here if yo want there is te perl script already implemented:
http://www.cyberciti.biz/faq/shell-scripting-run-command-under-alarmclock/
Utilization summary:
Create a file installTimeout.sh containing the following:
wget http://pilcrow.madison.wi.us/sw/doalarm-0.1.7.tgz
tar -zxvf doalarm-0.1.7.tg
cd doalarm-0.1.7
make
and run the command:
source installTimeout.sh
now it's transparent to you.
When you want to give a timeout to your script yo just have to run:
doalarm 20 your script
Best,
Ste

How can i run perl script from anywhere in unix environment?

I have this perl script that I need to distribute to my coworkers who want to run the script from anywhere in the unix environment. What can I do on my part to make running this PERL script easy for them? For example, they can just have the PERL script somewhere in their directory and run just typing
./xyz.pl ttt.conf
with no path declared (like /home/abc/bin/ddd/xyz.pl ttt.conf).
The way I used to do it is add a "bin" directory in your home directory, and add it to the $PATH variable.. then you can add any script you want to use to that directory.
I am no longer familiar with the exact syntax, but something like:
in .bashrc:
$PATH = ( $PATH , $HOME/bin )
Then place the script in /home/user/bin (assuming $HOME == /home/user). When you reload the shell, it will be usable like any normal command/program.
ETA: See robert's comment below on syntax. Also, to allow your co-workers to use a script of yours, you can simply use a hard-coded path, such as /home/patrick/bin.
Put the script in /usr/local/bin (or anywhere else in $PATH). Your sysadmin may have to help you.
The technique I use is:
#!/usr/bin/env perl
This is a common way of getting the command interpreter to find Perl without either (a) moving the file, or (b) declaring the explicit path for Perl in the shebang.
It's mentioned under portability at: http://en.wikipedia.org/wiki/Shebang_(Unix)
You all are kind of right... but that perl script can sit in your path till the cows come home... and it ain't gonna run... until you set the executable bit....
:bin localadmin$ ./perlextip
-bash: ./perlextip: Permission denied
:bin localadmin$ chmod +x perlextip
:bin localadmin$ ./perlextip
Exit 0! Yeehaw.
Also, it should be noted that it need not be IN your path.... You can just call it by the full path, preceeded with a period and a slash, to execute it..
:/ localadmin$ ./ServiceData/UNIX/bin/extip
Exit 0! Yeehaw.
You can also create an alias for such a command in your ~/.bash_profile, or the such, which will let you make a system-wide shortcut of sorts, and you can even throw in a sudo, or the like, if you were so inclined... Then just call that "extip" by name anywhere, you'll be prompted for a password and, all will be well in the world.
alias extip='sudo ./ServiceData/UNIX/bin/extip'

How do I fix "Permission denied" when I try to run an external Perl script?

system("logscr.ply ");
The error I get is this:
Can't exec "logscr.ply": Permission denied at eal.ply line 3
Why am I getting the error, and how do I fix it?
Without knowing any more details, there could be a variety of reasons:
Your example code states you're trying to execute "logscr.ply ". The space character at the end might be parsed as part of the file name. This should yield a file-not-found error, though.
The protection bits for the called script might not allow for direct execution. Try chmod u+x logscr.ply from your command prompt.
The folder containing logscr.ply might not be accessible to you. Make sure you have both read and execute permission on it (try chmod u+r,u+x folder-name).
The called script might not recognize itself as a Perl script, try system("perl logscr.ply");.
There might be a file with the same name somewhere earlier in your $PATH. Use absolute paths in your call to prevent this (system("perl /some/path/logscr.ply");), don't rely on your $PATH variable.
What platform/OS is this?
Probably logscr.ply just does not have execute permissions set. On Linux/Unix e.g. you should do
chmod u+x logscr.ply
then try again.
Note: This assumes you are the owner of logscr.ply. If not, adjust accordingly.

Why does my command-line not run from cron?

I have a perl script (part of the XMLTV family of "grabbers", specifically tv_grab_oztivo).
I can successfully run it like this:
/sw/bin/perl /path/to/tv_grab_oztivo --output /path/to/tv.xml
I use the full paths to everything to eliminate issues with the Working Directory. Permissions shouldn't be a problem.
So, if I run it from the Terminal (Mac OSX) it works just fine.
But when I set it to run via a cron job, nothing appears to happen at all. No output is created etc.
There isn't anything wrong with the crontab as far as I can see, because if I substitute a helloworld.pl for the actual script, it runs just fine at the right time.
So, what can I do to debug? I can see from looking at %ENV in the two cases that the environment is very different, but what other approaches can I take to debugging? How can I see the output of the cron job, which might be some kind of perl "die" message or "not found" message from the shell or whatever?
Or should I be trying to somehow give the cron version of the command the same environment as when it's running as me?
It's often because you don't get the full environment when running under cron. Best bet is to capture the ouput by using the command:
( /sw/bin/perl /path/to/tv_grab_oztivo ... ) >/tmp/qq 2>&1
and then have a look at /tmp/qq.
If it does turn out to be a missing environment, then you may need to put:
. ~/.profile
or something similar, into the execution chain of your cron job, such as:
( . ~/.profile ; /sw/bin/perl /path/to/tv_grab_oztivo ... ) >/tmp/qq 2>&1
If you're looking at %ENV in the two cases, I'd suggest that, as a first step in your perl script, set %ENV to what it is in a cron job, and then trying to run it from the command line. You may need to exec yourself once for this to take full control:
BEGIN {
if (exists $ENV{something_in_your_env_not_in_cron}) {
%ENV = (...);
exec $^X, $0, #ARGV;
}
}
Now try running it, and seeing if there's anything you can do to debug it (including running under perl -d if required). Most likely, you'll find that you end up adding items back into %ENV one at a time until it magically starts working (LD_LIBRARY_PATH is a good one for this, but ORACLE_HOME or DB2HOME for Oracle or DB2 apps might be good choices, too). Then you can either set the variable in your script, or in the crontab.
I'd run a simple shell script by absolute path from the cron command.
Inside that script, I'd ensure that I trapped stdout and stderr to a known (or knowable) file. I'd also ensure that enough of your environment is set. On Unix, you get almost no environment set at all when you run a command via cron - I'm not sure about MacOS X. The standard culprit for problems is PATH. I have a separate .cronfile that sets my working environment enough that I usually don't have problems - that's an analogue of .profile.
On occasion if you can't figure out what's going wrong with your command line, the simplest way to fix it is to turn the whole thing into a shell script. Ideally you shouldn't have to do this, but it can be the fastest way to solve the problem.
File: /files/cron1.sh
#!/bin/sh
/sw/bin/perl /path/to/tv_grab_oztivo --output /path/to/tv.xml
And then in cron:
/files/cron1.sh
This allows you to test the script independent of cron. Remember though that your login shell runs with different environment variables than cron does.
cron usually captures the output of stdout and stderr and e-mailes any output to the crontab owner.
Did you double check your crontab entry to make sure it's valid and will execute at the right time?
Make sure that the script does not need any environment variables set. Otherwise wrap it in another (bash) script, where you can set the environment variables that the other script expects.