Get Script Path

Reliable way for a Bash script to get the full path to itself

Here's what I've come up with (edit: plus some tweaks provided by sfstewman, levigroker, Kyle Strand, and Rob Kennedy), that seems to mostly fit my "better" criteria:

SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

That SCRIPTPATH line seems particularly roundabout, but we need it rather than SCRIPTPATH=`pwd` in order to properly handle spaces and symlinks.

The inclusion of output redirection (>/dev/null 2>&1) handles the rare(?) case where cd might produce output that would interfere with the surrounding $( ... ) capture. (Such as cd being overridden to also ls a directory after switching to it.)

Note also that esoteric situations, such as executing a script that isn't coming from a file in an accessible file system at all (which is perfectly possible), is not catered to there (or in any of the other answers I've seen).

The -- after cd and before "$0" are in case the directory starts with a -.

How do I get the directory where a Bash script is located from within the script itself?

#!/usr/bin/env bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

is a useful one-liner which will give you the full directory name of the script no matter where it is being called from.

It will work as long as the last component of the path used to find the script is not a symlink (directory links are OK). If you also want to resolve any links to the script itself, you need a multi-line solution:

#!/usr/bin/env bash

SOURCE=${BASH_SOURCE[0]}
while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
SOURCE=$(readlink "$SOURCE")
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )

This last one will work with any combination of aliases, source, bash -c, symlinks, etc.

Beware: if you cd to a different directory before running this snippet, the result may be incorrect!

Also, watch out for $CDPATH gotchas, and stderr output side effects if the user has smartly overridden cd to redirect output to stderr instead (including escape sequences, such as when calling update_terminal_cwd >&2 on Mac). Adding >/dev/null 2>&1 at the end of your cd command will take care of both possibilities.

To understand how it works, try running this more verbose form:

#!/usr/bin/env bash

SOURCE=${BASH_SOURCE[0]}
while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET=$(readlink "$SOURCE")
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE=$TARGET
else
DIR=$( dirname "$SOURCE" )
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE=$DIR/$TARGET # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR=$( dirname "$SOURCE" )
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"

And it will print something like:

SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'

Unix shell script find out which directory the script file resides?

In Bash, you should get what you need like this:

#!/usr/bin/env bash

BASEDIR=$(dirname "$0")
echo "$BASEDIR"

Get the path of current script

In RStudio, you can get the path to the file currently shown in the source pane using

rstudioapi::getSourceEditorContext()$path

If you only want the directory, use

dirname(rstudioapi::getSourceEditorContext()$path)

If you want the name of the file that's been run by source(filename), that's a little harder. You need to look for the variable srcfile somewhere back in the stack. How far back depends on how you write things, but it's around 4 steps back: for example,

fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi

should print the same thing on the last two lines.

How to retrieve the current script's path in Fish shell

status --current-filename is what you're looking for.

Note that this handles both sourced and executed files, while $0 in bash is only for executed files.

Getting the full path the script is currently running in [Python]

Let me explain to you by explaining the outputs of all the commands you mentioned by running them in Windows.

Nothing special here, just importing some modules. Importing numpy to test the commands.

In [1]: import os
...: import sys
...: import numpy

This gives the current working directory in which your process/program is executing. (detailed tutorial here)

In [2]: os.getcwd()
Out[2]: 'C:\\Users\\<username>'

This tells which file the module is loaded from which file.

In [3]: numpy.__file__
Out[3]: 'C:\\Users\\<username>\\anaconda3\\lib\\site-packages\\numpy\\__init__.py'

The path of the loaded file for the module, it can be a relative path.

In [4]: os.path.dirname(numpy.__file__)
Out[4]: 'C:\\Users\\Punit Singh\\anaconda3\\lib\\site-packages\\numpy'

The actual path of the loaded file for the module. See the difference from previous in lib and Lib. The folder name actually starts from the capital letter.

In [5]: os.path.dirname(os.path.realpath(numpy.__file__))
Out[5]: 'C:\\Users\\Punit Singh\\anaconda3\\Lib\\site-packages\\numpy'

This is the absolute path, you'll see the difference when you'll run this in Linux. It starts with the root folder denoted by \.

In [6]: os.path.dirname(os.path.abspath(numpy.__file__))
Out[6]: 'C:\\Users\\Punit Singh\\anaconda3\\lib\\site-packages\\numpy'

[7] and [8] respectively give the path and absolute path of the file which is currently executing, here sys.argv[0] returns the file which is currently executing, since currently, I am running ipython, it is ipython.exe shown in [9]. (detailed tutorial here)

In [7]: os.path.dirname(sys.argv[0])
Out[7]: 'C:\\Users\\<username>\\anaconda3\\Scripts'

In [8]: os.path.abspath(os.path.dirname(sys.argv[0]))
Out[8]: 'C:\\Users\\<username>\\anaconda3\\Scripts'

In [9]: sys.argv[0]
Out[9]: 'C:\\Users\\<username>\\anaconda3\\Scripts\\ipython'

This gives the absolute path of the executable binary for the Python interpreter (documentation here)

In [10]: sys.executable
Out[10]: 'C:\\Users\\Punit Singh\\anaconda3\\python.exe'

Now coming to your requirement, I understand that you need to access files where this ipython.exe as shown in [9] is located, so you can use commands mentioned in [7] or [8].

How do I get the path to the current script with Node.js?

I found it after looking through the documentation again. What I was looking for were the __filename and __dirname module-level variables.

  • __filename is the file name of the current module. This is the resolved absolute path of the current module file. (ex:/home/kyle/some/dir/file.js)
  • __dirname is the directory name of the current module. (ex:/home/kyle/some/dir)

What's the best way to determine the location of the current PowerShell script?

PowerShell 3+

# This is an automatic variable set to the current file's/module's directory
$PSScriptRoot

PowerShell 2

Prior to PowerShell 3, there was not a better way than querying the
MyInvocation.MyCommand.Definition property for general scripts. I had the following line at the top of essentially every PowerShell script I had:

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition

How to get the path of the batch script in Windows?

%~dp0 will be the directory. Here's some documentation on all of the path modifiers. Fun stuff :-)

To remove the final backslash, you can use the :n,m substring syntax, like so:

SET mypath=%~dp0
echo %mypath:~0,-1%

I don't believe there's a way to combine the %0 syntax with the :~n,m syntax, unfortunately.



Related Topics



Leave a reply



Submit