7

I have a script that is used to set some env vars in the calling csh shell. Some of those variables depend on the location of the script.

If the file is a proper csh script, I can use $0 to access __FILE__ but if I run the script using source, it just tells me csh or tcsh.

Since I'm using this to set vars in the parent shell, I have to use source.

What to do?

mmccoo
  • 8,386
  • 5
  • 41
  • 60

4 Answers4

3

If you access $_ on the first line of the file, it will contain the name of the file if it's sourced. If it's run directly then $0 will contain the name.

#!/bin/tcsh
set called=($_)
if ($called[2] != "") echo "Sourced: $called[2]"
if ($0 != "tcsh") echo "Called: $0"
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 1
    That is easy to break: If you chain commands with ";", then called will return the wrong info. `echo HELLO; source test.csh` `HELLO` `Sourced: HELLO;` `Called: /bin/tcsh` ` – engtech Apr 29 '13 at 15:53
  • @engtech: That's because `$_` really "Substitutes the command line of the last command executed." – Dennis Williamson Apr 29 '13 at 16:12
2

This is hard to read, but is actually works:

If your script is named test.csh

/usr/sbin/lsof +p $$ | \grep -oE /.\*test.csh

engtech
  • 2,791
  • 3
  • 20
  • 24
  • 1
    I like this better than the accepted answer. Using $\_ _only_ works if you can tightly control exactly how the script is sourced. – Dustin R Aug 04 '16 at 14:41
  • What does the lsof option *+p* do? I think the option should be *-p* to select the process number of the parent shell, so `/usr/sbin/lsof -p $$ | grep -oE /.\*test.csh`. https://linux.die.net/man/8/lsof – Snowrabbit Jan 04 '21 at 16:05
1

this answer describes how lsof and a bit of grep magic is the only thing that seems to stand a chance of working for nested sourced files under csh/tcsh.

If your script is named source_me.tcsh:

/usr/sbin/lsof -p $$ | grep -oE '/.*source_me\.tcsh'
Snowrabbit
  • 152
  • 3
  • 8
Patrick Maupin
  • 8,024
  • 2
  • 23
  • 42
0

The $$ does not work when one calls the source within a sub-shell. BASH_PID only works in bash.

% (sleep 1; source source_me.csh)

I found the following works a bit better:

% set pid=`cut -d' ' -f4 < /proc/self/stat`
% set file=`/usr/sbin/lsof +p $pid|grep -m1 -P '\s\d+r\s+REG\s' | xargs | cut -d' ' -f9`

First line finds the pid of the current process that is sourcing the file. This came from Why is $$ returning the same id as the parent process?. The second line finds the first (and hopefully only) FD opened for read of a regular file. This came from engtech above.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77