can't source script in a current directory
Quoting the source man page:
source filename [arguments]
....
If filename does not contain a slash, file
names in PATH are used to find the directory containing file-
name.
So... source
is trying to search your script.sh
in the folders contained in PATH
.
If you want to source a file in the current folder use
source ./script.sh
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'
Run a script in the same directory as the current script
Since $0
holds the full path of the script that is running, you can use dirname
against it to get the path of the script:
#!/bin/bash
script_name=$0
script_full_path=$(dirname "$0")
echo "script_name: $script_name"
echo "full path: $script_full_path"
so if you for example store it in /tmp/a.sh
then you will see an output like:
$ /tmp/a.sh
script_name: /tmp/a.sh
full path: /tmp
so
- Knowing the current working directory is useless to me, because I don't know how the user is executing the first script (could be with
/usr/bin/script.sh
, with./script.sh
, or it could be with
../Downloads/repo/scr/script.sh
)
Using dirname "$0"
will allow you to keep track of the original path.
- The script
script.sh
will be changing to a different directory before callinghelper.sh
.
Again, since you have the path in $0
you can cd
back to it.
R command for setting working directory to source file location in Rstudio
To get the location of a script being sourced, you can use utils::getSrcDirectory
or utils::getSrcFilename
. So changing the working directory to that of the current file can be done with:
setwd(getSrcDirectory()[1])
This does not work in RStudio if you Run the code rather than Sourceing it. For that, you need to use rstudioapi::getActiveDocumentContext
.
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
This second solution requires that you are using RStudio as your IDE, of course.
How can I set the current working directory to the directory of the script in Bash?
#!/bin/bash
cd "$(dirname "$0")"
Related Topics
Process Stuck in Exit, Shows as Zombie But Cannot Be Reaped
Fatal: Bad Config File Line 1 in /Home/Trx/.Gitconfig
Bash Completion for Path in Argument (With Equals Sign Present)
How to Grep While Avoiding 'Too Many Arguments'
Parsing Data from Ifconfig with Awk or Sed
Ignore Case When Trying to Match File Names Using Find Command in Linux
Is It Good Practice to Use Mkdir as File-Based Locking on Linux
Can Any One Say How to Install the Slack in Ubuntu14.04 and While Trying This Was the Error
Differenceamong Three Priorities Used in Linux Kernel
How to Autocomplete a Bash Commandline with File Paths
How to Add Boost Library to Code::Blocks in Linux
Read File Without Disk Caching in Linux
Configure Options for Building Mingw-64 on Linux-64 for Linux-64 (Ultimately Targetting Windows-64)
How Can Linux Ptrace Be Unsafe or Contain a Race Condition
Access Bash Positional Parameter Through Variable
How to Get Environment Variables of Remote Host
Bash: How to Traverse Directory Structure and Execute Commands