Can't Source Script in a Current Directory

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

  1. 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.


  1. The script script.sh will be changing to a different directory before calling helper.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



Leave a reply



Submit