01-19-2006 06:47 AM
For example, if the current directory is "/database/app" and the user passes "../bin", I need to expand it to "/database/bin". Or if the current directory is "/database/app" and the user passes "../bin/myfile.txt" I need it to expand to "/database/bin/myfile.txt".
I've come up with a way to brute force the result but I have to believe there's an easier way. I've included my brute force method in an attachment.
Any help would be appreciated.
Solved! Go to Solution.
01-19-2006 06:55 AM
If you need to use expanded path in the script, use, if the path is the first parameter:
If you want to expand path for your interactive shell, run
. script dirname
after the shell prompt.
The script should contain the same string
01-19-2006 07:03 AM
I don't understand whell what you need to do, because if are in /database/app and you use the ../bin or replace by /database/bin, you have the same results. I don't see the difference.
01-19-2006 07:26 AM
Apparently my original explanation was not clear. When I stated that I need to be able to expand a path, I did not mean PATH, I was simply referring to any combination of typed directories the user may pass to a script, which is why I included examples.
As to the reason this is required; while you are correct that the examples I gave are equivalent within the shell, the relative paths have no meaning to another user viewing the results unless they know where the script was run from in the first place. This particular script can be run from anywhere on the system and the results have to indicate absolute paths in order to make any sense.
If that were the only issue, simply reporting the starting directory would reoslve the problem. However, absolute paths are a must when the results have to be sortable in a spreadsheet by path. Attempting to sort relative paths and make any sense of them is impossible.
I hope this helps clarify what I'm looking for.
01-19-2006 07:47 AM
Then, in your script, always use:
So, if APP_PATH is /database/app, and the user passes ../bin, doest matter where he is, he will go to
/database/app/../bin -> /database/bin
01-19-2006 07:58 AM
# cat getpath
WHERE=`perl -le 'use Cwd qw(realpath);print realpath $ARGV;' $1`
# cd /var/tmp/dummydir && ./getpath ../bin
Does that help? This is based on the realpath() C library function.
01-19-2006 07:59 AM
Again, the issue isn't manipulating directories within the shell, it's being able to report the absolute path, even if the user specified a relative one.
The answer is straight-forward if the user actually passes a directory but if they pass a filename, it gets much trickier as you can see from the brute force method I uploaded.
01-19-2006 08:05 AM
Your answer looks like it's on the right track but I get the following error when i attempt to run it:
Can't locate Cwd.pm in @INC (@INC contains: /opt/perl5/lib/5.00502/PA-RISC1.1 /opt/perl5/lib/5.00502 /opt/perl5/lib/site_perl/5.005/PA-RISC1.1 /opt/perl5/lib/site_perl/5.005 .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
01-19-2006 08:11 AM
It appears that the 'Cwd' module required isn't in your rather old version of perl.
You could download the module from CPAN:
...or better, yet, upgrade your version of perl:
01-19-2006 08:16 AM
Leif - Thanks for the input but dirname and basename do not expand relative paths. They were one of my first attempts.
James - I appricate the quick response. I'll look into updating my perl and let you know how it turns out.
Thanks to all,
01-19-2006 08:17 AM
FULLPATH=`cd $APP_PATH/$1; pwd`
01-19-2006 08:20 AM
RELATIVE=`echo $1 |grep "^\."|wc -l`
# If the arg starts with dot, then is a relative path, else just use the specified path
if [ $RELATIVE -gt 1 ]; then
01-19-2006 08:22 AM
Your solution works if the user passes a directory, and is very similar to the method I uploaded. However if they are passing a filename, it gets an error.
I need a solution for both possibilities.
Thanks for the continued effort.
01-19-2006 08:29 AM
01-19-2006 08:31 AM
Your new solution works in most cases but not all. If you pass it a sub-directory of the current directory, it will return the current directory, instead of the full path to the sub-directory.
Your first solution did not have this problem. Also, this solution still can't handle a filename.
01-19-2006 08:34 AM
it should work also with an absolute path or a filename only
01-19-2006 08:36 AM
-- Rod Hills
01-19-2006 08:45 AM
Very close! However, if the user passes a path or filename that is already in absolute format (i.e. /home), your solution doubles the initial forward slash (i.e. //home). If they pass the root directory, it returns three forward slashes (i.e. ///).
Thanks for the effort,
01-19-2006 08:58 AM
RELATIVE=`echo $1 |grep "^\."|wc -l`
# If the arg starts with dot, then is relative
if [ $RELATIVE -gt 0 ]; then
if [ -d $APP_PATH/$1 ]; then
01-19-2006 09:12 AM
Not having much experience with compiling programs for Unix, I compiled it with no options and it works perfectly. None of the tests I've run have failed (unless the user provides a bogus entry but then there are larger problems anyway).
This has the added convenience of completely encapsulating the code in a single command for use in my scripts, keeping the complexity of the scripts themselves to a minimum.
I'm still going to upgrade my perl and check out that solution but I'm going to be using this as the permanent fix.
01-19-2006 09:14 AM
I appreciate the effort but what your suggesting is already as large as the brute force method I uploaded at the beginning of this thread.
As you can see from the previous post, Rodney posted a simple C program that will wrap it all up nicely for me.
01-19-2006 09:25 AM
...and I can't resist noting that Rodney's C-code leverages the 'realpath()' function that the perl module I suggested you use does. :-;
01-20-2006 12:39 AM
I was able to get the perl solution to work by pointing it to the newer version as shown here:
WHERE=`perl5.6.1 -le 'use Cwd qw(realpath);print realpath $ARGV;' $1`
Actually, I will likely use the perl solution in some cases and the compiled C solution in others.
The difference is, as provided above, the perl solution will generate an error if an invalid directory is passed, while the C solution will not.
Each solution has it's own merits depending on what exactly you're trying to accomplish and if/how you're going to handle invalid paths.
I want to thank everyone on this forum for their prompt responses and dedication to helping me find a workable solution. This has been a very enjoyable first experience.