How does a ksh script determine the full path to itself when it comes from another?

How does a script determine the path when it is obtained using ksh? i.e.

$ ksh ". foo.sh" 

I have seen very good ways to do this in BASH hosted on stackoverflow and elsewhere, but have not yet found the ksh method.

Using "$ 0" does not work. It just means "ksh".

Update: I tried using the "history" command, but did not know about the history outside the current script.

 $ cat k.ksh #!/bin/ksh . j.ksh $ cat j.ksh #!/bin/ksh a=$(history | tail -1) echo $a $ ./k.ksh 270 ./k.ksh 

I would like this echo "*. / J.ksh".

+4
source share
4 answers

I believe the only portable solution is to override the source command:

 source() { sourced=$1 . "$1" } 

And then use the source instead. (the script name will be in $ sourced).

+1
source

If it is AT & T ksh93 , this information is stored in the .sh namespace in the .sh.file variable.

Example

sourced.sh :

 ( echo "Sourced: ${.sh.file}" ) 

Vocation:

 $ ksh -c '. ./sourced.sh' 

Result:

 Sourced: /var/tmp/sourced.sh 

The .sh.file variable .sh.file different from $0 . As long as $0 can be ksh or /usr/bin/ksh , or the name of the current script, .sh.file will always refer to the file of the current area.

In the interactive shell, this variable does not even exist:

 $ echo ${.sh.file:?} -ksh: .sh.file: parameter not set 
+4
source

The difference between searching and forcing is that searching for the source executes the called script in the calling process. Henk showed an elegant solution in ksh93, but if, like me, you are stuck with ksh88, then you need an alternative. I would prefer not to change the default ksh method using the C-shell syntax, and at work this would be against our coding standards, so creating and using the source () function would not work for me. ps, $ 0 and $ _ are unreliable, so there is an alternative here:

$ cat b.sh; cat c.sh; ./ b.sh

 #!/bin/ksh export SCRIPT=c.sh . $SCRIPT echo "PPID: $$" echo "FORKING c.sh" ./c.sh 

If we set the script to be called into a variable and correct it with a variable, this variable will be accessible to the script being called, since they are in the same process space.

 #!/bin/ksh arguments=$_ pid=$$ echo "PID:$pid" command=`ps -o args -p $pid | tail -1` echo "COMMAND (from ps -o args of the PID): $command" echo "COMMAND (from c.sh \$_ ) : $arguments" echo "\$SCRIPT variable: $SCRIPT" echo dirname: `dirname $0` echo ; echo 

The output is as follows:

 PID:21665 COMMAND (from ps -o args of the PID): /bin/ksh ./b.sh COMMAND (from c.sh $_ ) : SCRIPT=c.sh $SCRIPT variable: c.sh dirname: . PPID: 21665 FORKING c.sh PID:21669 COMMAND (from ps -o args of the PID): /bin/ksh ./c.sh COMMAND (from c.sh $_ ) : ./c.sh $SCRIPT variable: c.sh dirname: . 

Therefore, when we set the script variable in the calling script, the variable is either accessible from the operands of the script, or, in the case of a forked process, the variable, along with all other environment variables of the parent process, is copied to the child process. In any case, the script variable may contain your command and arguments and will be available in the case of both sources and forking.

+1
source

You should find him as the last team in history.

0
source

All Articles