I have a perl script exist in the follwoing path (/home/Leen/Desktop/Tools/bin/tool.pl)
Every time I want to run this tool I go to the terminal
>
and then change the directory to
..../bin>
Then I run the perl by writing
..../bin> perl tool.pl file= whatever config= whatever
The problem is that I want to run this perl script without the need to go to the bin folder where it exist . so I can run perl script from any directory and as soon as I enter shell
I went to the etc/environment and I wrote the follwoing
export PERL5LIB=$PERL5LIB:/home/Leen/Desktop/Tools/bin
But when I go to terminal and write the follwoing straight ahead without going to bin folder where tool.pl exist
>perl tool.pl file=... config=...
it says the file "tool.pl" does not exist???
The first argument to the perl program is the path to an executable file. These calls are equivalent:
:~$ perl /home/Leen/Desktop/Tools/bin/tool.pl
:~$ perl ~/Desktop/Tools/bin/tool.pl
:~$ perl ./Desktop/Tools/bin/tool.pl
:~/Desktop/Tools/bin$ perl tool.pl
:~/Desktop/Tools/bin$ perl ./tool.pl
etc.
In the shell the tilde ~ expands to your home directory, and ./ symbolizes the current directory. On *nix shells (including the various terminal emulators on ubuntu), the command prompt ususally is $ in nomal mode, # as root user and seldom %. > Is a secondary command prompt, e.g. when continuing a multiline argument, unlike cmd.exe on Windows.
The PERL5LIB variable determines where Perl looks for modules, not for executable files.
You can set a script as executable via chmod +x FILENAME. You can then call the script without specifying the perl program:
:~/Desktop/Tools/bin$ ./tool.pl
You can modify the PATH variable to change where the shell looks for executables. The PATH usually contains /usr/bin/ and other directories. You can add a directory of your own via
PATH=$PATH:/home/Leen/Desktop/Tools/bin
Add your directory at the end of the PATHes, so you don't overrule other programs.
If you want to set this permanently, you can add this line to the file ~/.bashrc (only for your user and only for the bash shell).
Then you can call your script from anywhere, without a full path name:
:~/foo/bar$ tool.pl
You should consider using a more specific command name in this case, to prevent name clashes.
Related
Running Lubuntu -
Beginner Perl programmer
Script is XXX.pl located at ~/projects/XXX/XXX.pl
First line is the shebang
#!/usr/bin/perl
Permission to run is set to Anyone.
In directory ~/projects/XXX, the command
~/projects/XXX$ perl XXX.pl
works as desired, but the command
~/projects/XXX$ XXX.pl
Fails with XXX.pl: command not found
What am I missing ?
The two usual options to execute your Perl script are:
perl XXX.pl
or
./XXX.pl
Both ways assume that your current working directory contains the script XXX.pl, otherwise it won't work.
As already pointed out by jm666 in the comments, you can usually not execute a program or script from your current working directory without prepending ./, primarily because of security reasons. Now, you may wonder why it's necessary.
Explanation:
Your shell uses the contents of an environment variable called $PATH to find out about where external commands (non-builtin programs) are located in your filesystem. If you want to see what's in $PATH, just type the following in your shell:
echo $PATH
Now you can see that the $PATH variable does NOT contain your current working directory. The consequence is that your shell is not able to find the program XXX.pl. By prepending ./ you instruct the shell to execute the program which comes after.
But there are two requirements if you want to execute your Perl script with ./script.pl:
The script has to be executable (check with ls -l)
The first line (shebang line) has to be #!/path/to/your/perl because your shell needs that information to find the perl interpreter in order to run your script
However, #1 and #2 are NOT required when you execute your script with
perl XXX.pl
because it invokes the perl interpreter directly with your script.
See how to make Perl scripts executable on Linux and make the script itself directly executable with chmod for some more details.
Can the script be found?
Is . in your path? If it's not, add it to your path, or use ./XXX.pl instead of XXX.pl.
Can the script be executed?
Do you have execute permission to the file? Fix using chmod u+x XXX.pl.
Is the interpreter correct?
which perl will tell you which interpreter is used when you use perl XXX.pl. That's the path that should be on your shebang (#!) line.
I am trying to run a perl script from within a *.csh script, but I get the following error:
Can't open perl script "checkLength.perl": No such file or directory
I think it has something to do with the path of the perl script. I can run a perl script fine when it's not being called within the shell script, but a perl script won't run when I have it being called in the cshell script.
The shebang I use for the perl script is : #!/usr/bin/perl. I checked, and perl is located there (not in /usr/bin/env perl). I made sure it's executable.
Do I need to edit the $PATH to get this to work? I'm confused because if I run a perl script without calling it within another csh script, it runs just fine.
Of course one obvious solution to your problem would be to simply use the full path to the script. But this is often not preferable, as the script would brake on installations that do not mirror exactly the original structure.
So there are two possibilities:
Either you put your perl script into a well defined location that is contained in your PATH variable so any program that runs under the respective users environment finds it.
Or you have some well defined location relative to the location of your calling script. Say your bash script is located in somedir and you perl script is in somedir/subdir, then your call would be subdir/perlscript.pl. Then, to become independent of possible changes in the working directory of the caller, you could determine the current full path of the perl script to be called on start of the bash script.
A template for this would be:
#!/bin/bash
FULLPATH=$(pwd)/subdir/somescript.pl
# do something else, cd ...
$FULLPATH
I am assuming your Perl script is kept in a fixed path relative to your bash script. Assuming your directory structure to be like so:
(BASEDIR)/bin/example.sh
(BASEDIR)/perl/example.pl
To allow you to run your bash script from anywhere in your system you must specify the relative path to your Perl script by getting the BASEDIR.
#!/bin/bash
BASEDIR=$(dirname $0)
perl $BASEDIR/../perl/example.pl
What we are doing above is finding the location of your bash script(BASEDIR/bin) that you call and then finding the relative location of the Perl script using the location of the bash script as reference. Now you will be able to call the bash script from anywhere and run your Perl script normally.
I tried to implement a bash command system("cd /home/user") in perl , but I get an error saying
Can't exec "cd": No such file or directory at temp.pl
Is there a way to change the current working directory to the specified one , and the change remains after the perl script has exited also.
No. A process can't change its parent process's current working directory. Shells implement commands like cd as "builtins", meaning they're a function in the shell itself, and not a separate process that gets run.
You can change the current directory in perl using chdir($dir), and that change will be inherited by child processes — but it won't be passed along to the parent process.
When you want to change the directory inside your Script, you can use the Perl command chdir('dir')
Example:
chdir($dir);
You actually cant modify the directory of the parents process, but you can of the current process
You cannot modify the current working directory of a different process in UNIX, at least not without some serious hackery.
This is why cd is a built-in in all shells. It is not an external program (nor can it be implemented as an external program).
cd is not a process, it is a shell builtin command that changes the current working directory for that shell process.
So use system("sh -c 'cd /my/dir'"). but here system command itself invoke another shall so still it not change directory.
use chdir for that.
cd is not a process, it is a shell builtin command that changes the current working directory for that shell process. So system("sh -c 'cd /cat/bat'") would "succeed", but still wouldn't change the working directory of your perl process; use chdir for that.
I wrote a perl script which uses some linux commands (grep, ls etc..). I can successfully run this from Cygwin or Linux. I want this task to be run periodically on a Windows Server which has Cygwin installed. I was planning to use Windows task scheduler. But I am not sure how to specify in a Windows bat file, that my perl script needs to be called in Cygwin mode?
EDIT: I tried the command by Glenn. When I tried running the perl script, it doesn't seem to respond. So I tried with a sample script: test.sh, which has the following two lines:
ls -l
cd ..
Here is the screen capture of what I am getting:
I'm not a great fan of cygwin and personally prefer natively compiled versions of the GNU tools, e.g. GnuWin32.
I also wonder why you would be using grep, ls etc. from a Perl script. Most of that functionality can be handled natively by Perl and this usually results in much better portability and robustness.
Perhaps (untested): c:\cygwin\bash.exe -c /path/to/your/script.pl
UPDATE:
The last error message reveals one problem: your script is a DOS format file (CRLF line endings), while cygwin looks for UNIX format (LF line endings). The stray carriage returns at the end of each line is the problem. For example, there's no directory named "..\r"
Use a text editor where you can specify the line endings to use. In a bash shell, you can do dos2unix test.sh
The ls error indicates that /bin and /usr/bin are not in your bash environment's $PATH -- is that true?
Just add cygwin to your path before running perl. For example, I often run find in a dos shell, but get the rather horrible message FIND: Parameter format not correct. Bah! Instead I have to run find via a dos cmd file cyg.cmd:
c:> find . -iname interesting.txt
FIND: Parameter format not correct
c:> cyg find . -iname interesting.txt
sub/sub/interesting.TXT
c:> type bin\cyg.cmd
setlocal
PATH=c:\Progs\Cygwin\bin;%PATH%
%1 %2 %3 %4 %5 %6 %7 %8 %9
endlocal
The important bit here is the PATH=c:\Progs\Cygwin\bin;%PATH%.
BTW, I much prefer the cygwin versions of the tools rather than their MinGW equivalents—the environment is much closer to Mac/Linux, and portability is important after all.
You run cygwin bash, but you still have to setup your PATH. Unless you set it in your profile, but initialize the profile then with bash -i.
Either specify the full path to cygwin commands needed, like /bin/ls, /bin/grep,
or add c:\cygwin\bin and maybe other paths to your PATH beforehand.
2nd preferred. Like
schedule.bat:
PATH=C:\cygwin\bin;%PATH%
sh -c ./schedule.sh
schedule.sh:
#!/bin/sh
ls ...
grep ...
perl ...
schedule.sh gets the environment with the PATH from the parent process sh.exe, which inherits it from your bat.
Seperating shell scripts from batch files just for easier testing. You can call most cygwin programs from cmd.exe also.
You cannot set /usr/bin in your DOS PATH, DOS will not have a c:/usr directory. And it only works if you are in C:
Maybe it's dumbest question in the world, but I seriously have problems with it and could use help. I am trying to run perl script on linux. It's a simple text editing script, nothing fancy. I googled for it and I found that I had to chmod +x it and then just run myscript.pl in the console. Since it's supposed to modify a text file I did myscript.pl > myfile.txt after chmoding it
But it doesn't work. I get: bash: perl myscript.pl: command not found
Unless myscript.pl is in your path you will need to specify the current directory.
$ ./myscript.pl
You can check if the current directory is in your path with $ echo $PATH. If you're frequently using this script you can put it in the path by moving it to a directory that's part of your path, usually ~/bin.
Or by adding the current directory to the $PATH environment variable. Check the documentation for your shell for instructions.
Can you post the first few lines of your script?
Specifically, if you have #!/usr/bin/perl are there any typos on that line, extra spaces, etc.?
Also do a ls /usr/bin/perl (or whatever is on that line) to make sure it's actually there.
It doesn't look like perl is installed on your Linux machine. Do you get the same thing when you try this: # perl -e 'print "hi";' ?
As Chirael said, it sounds like your shebang line (the directive at the top of the file, that tells the shell how to run the script) is invalid somehow. You can bypass the shebang line entirely by invoking your script as:
perl myscript.pl > myfile.txt
You also don't need to set the script's executable bit, as with this method of invocation, you are only reading the script, not executing it (from the shell's perspective).
According to this thread, it could be from different representation of the new line.
Have you written the script on a windows box and copied over to your linux box?
What is your text editor?
I had the same issue, and traced it to DOS line endings (^M). Running dos2unix on the .pl file fixed the issue.
Please use,
./myperl.pl > outfile.txt
to give the current directory path
thanks