Let’s say I have a script named test1.sh that looks like this:
#!/bin/sh
PWD=$PWD/dirname $0
cat file1.txt
That script and the file file1.txt resides in a subdirectory named sub1. Then I run that script with the following command:
sh sub1/test1.sh
I was hoping that setting PWD would influence test1.sh to find and print the contents of file1.txt, but no. Since test1.sh was called from a directory level above sub1, it looks for file1.txt there.
Is there an easy way to make this work, that is to somehow set the environment for a script to run with all it’s references from the folder where it resides and not from where it was called?
If called with an absolute path, the path is in $0.
If called with a relative path, it can append $0 to the output of the pwd command.
But better still don’t use external text files in the shell script, you can often replace them with literal strings in the script or here documents. E.g.
IMHO you can not set the PWD parameter. It is set by the shell and contains: “The present working directory set by the **cd **command”. And that is (and should be) the only way to alter the PWD parameter.
The man page on the system differs from the one in my manual. It says:
“This variable shall represent an absolute pathname of the current working directory. Assignments to this variable may be ignored unless the value is an absolute pathname of the current working directory and there are no filename components of dot or dot-dot”.
Hm, sounds strange to me, I read this as: it can be assigned as it is what it already is.
My conclusion, use cd to change your working directory (and PWD will change to reflect this).
Well, the text file was just an example of relative reference. In my actual case I have several scripts in a directory structure calling each other. Always calling with an absolute path makes things inflexible, and the long pathnames messes up the code.
I could of course prepend the output of dirname $0 to every reference in all scripts. I was just hoping there was a way to change the environment to accomplish that automatically.
I am not sure I understand completely what your lay out is (in fact I am pretty sure I don’t ), but in a (may be) similar case, I start every script with setting variables to the different directories where scripts are:
This (long) range of statements can be put in a seperate file (containing just this AB=/a/b/c/ things), which you then can call in all your scripts with:
. /home/henk/thebasics/scriptplaces
(Mind the DOT SPACE in the beginninmg).
You then have a central place where you can edit a directory path and it will be known by all scripts.
Hope this gives some inspiration.
And sorry for using ksh syntax, much more readable to me, I never use the pwd but rather $(pwd).
Yes it does. That will most likely be the way I do it.
Though I still think an option to the shell telling it to execute a command file from where it resides (as opposed to where it was called from) would be a useful feature. Any shell developers reading this?
well… correct me if I’m wrong but doesn’t basename strip leading directory path from it’s argument, so that:
basename ${0}/program
would simply become:
program
which of course would work as long as the calling shell script and the called program reside in the same directory (as you said). But if called from another directory, as was my original intent, program would not be found, right? :\
So why did I not type what I want?? >:(
That is because I am only human and no computer.
I hope you will forgive me for typing this big nonsense :shame: