Reputation: 14090
In bash shell I can get a full path of a script even if the script is called by source, link, ./..., etc. These magic bash lines:
#Next lines just find the path of the file.
#Works for all scenarios including:
#when called via multiple soft links.
#when script called by command "source" aka . (dot) operator.
#when arg $0 is modified from caller.
#"./script" "/full/path/to/script" "/some/path/../../another/path/script" "./some/folder/script"
#SCRIPT_PATH is given in full path, no matter how it is called.
#Just make sure you locate this at start of the script.
SCRIPT_PATH="${BASH_SOURCE[0]}";
if [ -h "${SCRIPT_PATH}" ]; then
while [ -h "${SCRIPT_PATH}" ]; do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
pushd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
How can you get the script path under the same conditions in TCSH shell? What are these 'magic lines'?
P.S. It is not a duplicate of this and similar questions. I'm aware of $0
.
Upvotes: 1
Views: 3932
Reputation: 2791
IF your csh script is named test.csh, then this will work:
/usr/sbin/lsof +p $$ | \grep -oE /.\*test.csh
Upvotes: 2
Reputation: 753675
I don't use tcsh
and do not claim guru status in it, or any other variant of C shell. I also firmly believe that Csh Programming Considered Harmful contains much truth; I use Korn shell or Bash.
However, I can look at manual pages, and I used the man page for tcsh (tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-apple-darwin)
on MacOS 10.7.1 Lion).
As far as I can see, there is no analogue to the variable ${BASH_SOURCE[0]}
in tcsh
, so the starting point for the script fragment in the question is missing. Thus, unless I missed something in the manual, or the manual is incomplete, there is no easy way to achieve the same result in tcsh
.
The original script fragment has some problems, too, as noted in comments. If the script is invoked with current directory /home/user1
using the name /usr/local/bin/xyz
, but that is a symlink containing ../libexec/someprog/executable
, then the code snippet is going to produce the wrong answer (it will likely say /home/user1
because the directory /home/libexec/someprog
does not exist).
Also, wrapping the while
loop in an if
is pointless; the code should simply contain the while
loop.
SCRIPT_PATH="${BASH_SOURCE[0]}";
while [ -h "${SCRIPT_PATH}" ]; do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
You should look up the realpath()
function; there may even be a command that uses it already available. It certainly is not hard to write a command that does use realpath()
. However, as far as I can tell, none of the standard Linux commands wrap the realpath()
function, which is a pity as it would help you solve the problem. (The stat
and readlink
commands do not help, specifically.)
At its simplest, you could write a program that uses realpath()
like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
for (int i = 1; i < argc; i++)
{
char *rn = realpath(argv[i], 0);
if (rn != 0)
{
printf("%s\n", rn);
free(rn);
}
else
{
fprintf(stderr, "%s: failed to resolve the path for %s\n%d: %s\n",
argv[0], argv[i], errno, strerror(errno));
rc = EXIT_FAILURE;
}
}
return(rc);
}
If that program is called realpath
, then the Bash script fragment reduces to:
SCRIPT_PATH=$(realpath ${BASH_SOURCE[0]})
Upvotes: 0