Get location of "source"ed script - linux

I want to execute statements like (shell is bash)
/# source /workspace/scripts/script.sh
/workspace/scripts# source script.sh
Inside the script.sh I want to get its own location. (script.sh wont be in the PATH variable)
I could do this using readlink -f $0 when run the script, but the same doesnt work when I source it.
I dont want the solution to be dependent on where I run the source command from. (otherwise pwd would have been enough)
Is this possible?

It is not possible to find the location reliably in 100% of all cases.
If you use bash your best bet is $BASH_SOURCE variable.
This link is very helpful on this topic.

Since script.sh is in your path, you should be able to get it's full path using which. So, in the script, if $0 isn't a full path, you can do which $0.
carabiner$ cat ~/bin/test.sh
#!/bin/sh
echo test - $0 $1
which $0
carabiner$ source test.sh
test - test.sh
test.sh is /home/zigdon/bin/test.sh

Related

Bash script that would give out information about the desired directory

I need a script that would be similar to the ls and dir commands. To display information about the needed directory.
#!/bin/bash
for entry in *
do
echo "$entry"
done
But this script outputs files only in the directory where the script is located. How do I make the output in the directory that I need?
you can accept args with $1, etc. and refer to them later
for file in "$1"; do
This APP provides a better way to learn and understand unix/linux. I would like to suggest you to take a look.
https://play.google.com/store/apps/details?id=com.kanha.unixlinuxpocketbook
#!/bin/bash
for entry in /dir/I-need/*
do
echo "$entry"
done
also may be you would like
find /dir/I-need

Absolute and relative path in Linux

I am writing a shell script which runs pwd command and uses its output for some others tasks performed by the script. The script is working totally fine when I go to the particular directory and run it. But when I am trying to run the script from some other location by giving the full path of the script, I am not getting the desired output as pwd command gives current directory's path. How can I solve this issue? How can I write something that will hold correct irrespective of where I run the script from?
The same issue is being faced when I am using ..to get to previous directory. I want the script to take path with respect to its location instead of path where the script is being run. Please let me know if there are some other details required.
You can use $0 to extract script and then combine it with pwd
$ cat abc.sh
echo $0
DIR1=$(dirname `pwd`/$0)
echo $DIR1
DIR2="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo $DIR2
There are other ways to achieve it in all cases:
Reliable way for a bash script to get the full path to itself?
Getting the source directory of a Bash script from within

How to modify a file name within a shell script?

I am writing a shell script to sync to a github repo, kick off the build, then take the output file, rename it, and move it to a location where it can be seen by Apache.
It's the renaming of the file that I've got not the faintest how to do within a shell script (I have virtually no experience with shell scripts - my understanding
Compiler will create /var/espbuild/firstpart_1vXX_secondpart.bin
I need to move this file to:
/var/www/html/builds/espbuild/firstpart_1vXX_DATE_secondpart_postfix.bin
1vXX is the version number
DATE is the output of date +%m-%d
postfix is just a string.
I'm not really certain where to start for something like this - I'm sure there's a graceful way, since this is the kind of thing shell scripts are made for, but I know just about nothing about shell scripts.
Thanks in advance
You can get the result of a command into a variable by using $():
DATE=$(date +%m-%d)
Then just use it in the new filename:
INPUT=/var/espbuild/firstpart_1vXX_secondpart.bin
OUTPUT=/var/www/html/builds/espbuild/firstpart_1vXX_${DATE}_secondpart_postfix.bin
mv ${INPUT} ${OUTPUT}
Edit: To get out the version part, here's a quick example:
VERSION=$(grep -o 1v.. <<< ${INPUT})
Then OUTPUT should be set like:
OUTPUT=/var/www/html/builds/espbuild/firstpart_${VERSION}_${DATE}_secondpart_postfix.bin
You can use this in BASH:
f='/var/espbuild/firstpart_1vXX_secondpart.bin'
s="${f##*/}"
s2=${s##*_}
dest="/var/www/html/builds/espbuild/${s%_*}_$(date '+%m-%d')_${s2%.*}_postfix.bin"
echo "$dest"
/var/www/html/builds/espbuild/firstpart_1vXX_07-14_secondpart_postfix.bin
cp "$f" "$dest"

How to make my BASH script know the path that is saved

I'm going to mk a script that when you run it, it creates a html page with user's computer details... But I only have one problem...
If the user put that script in a folder and set it as a cronjob, when the crontab execute it, the script makes a folder in home directory and that is bad, because, I want the script to make the folder with the HTML docs at the same dir that the script is... what can I do??
thnx ;-)
I would usually do the following:
#!/bin/bash
# sample script to change directory and save a file
WORKDIR=/home/file/n34_panda
cd $WORKDIR
echo "this "> newfile.txt
This is a simple answer without reviewing the rest of your code. To be honest the simplest method would be simply adding the command:
cd /path/to/html/docs
Then after that you can add the rest of your code
Try this script from several directories. It will always return its location.
#!/bin/bash
echo ${0%/*}
You can simply set cron as below :
# m h dom mon dow command
* * * * * cd /path-where-you-want-to-save/ && /path/of/yourscript.sh
As suggested in the comments, there are ways of a script knowing what directory it is stored in. However, I would recommend a simpler solution. Use absolute file paths in the script. The destination directory could be an argument to the script. This make the script more flexible; it means that you don't have to have many copies stored in separate directories if you want to do the same task in more than one place.
#!/bin/bash
output_dir="$1" # first argument to the script
echo "blah blah" > "$output_dir"/filename
Using bash parameter expansion (https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) to extract the path from the special variable $0 (which stores the name of the script) if executed from a remote folder and the current directory otherwise ($0 will not contain full path if executed from current directory).
#!/bin/bash
if [[ "$0" == */* ]]; then
script_path=${0%/*}
else
script_path=$(pwd)
fi
I am testing if the special variable $0 contains a /. if so then use parameter expansion to truncate everything following the last /. If it does not contain / then we must be in the current directory, so store the result of pwd.
From my testing this allowed me to get the same output if executed as /pathTo/script.sh or pushd /pathTo; ./script.sh; popd
I tested this in Cygwin with GNU bash, version 4.3.42

How to include file in a bash shell script

Is there a way to include another shell script in a shell script to be able to access its functions?
Like how in PHP you can use the include directive with other PHP files in order to run the functions that are contained within simply by calling the function name.
Simply put inside your script :
source FILE
Or
. FILE # POSIX compliant
$ LANG=C help source
source: source filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
Above answers are correct, but if you run script in another folder, there will be some problem.
For example, a.sh and b.sh are in same folder,
a use . ./b.sh to include b.
When you run script out of the folder, for example, xx/xx/xx/a.sh, file b.sh will not found: ./b.sh: No such file or directory.
So I use
. $(dirname "$0")/b.sh
Yes, use source or the short form which is just .:
. other_script.sh
Syntax is source <file-name>
ex. source config.sh
script - config.sh
USERNAME="satish"
EMAIL="satish#linuxconcept.com"
calling script -
#!/bin/bash
source config.sh
echo Welcome ${USERNAME}!
echo Your email is ${EMAIL}.
You can learn to include a bash script in another bash script here.
In my situation, in order to include color.sh from the same directory in init.sh, I had to do something as follows.
. ./color.sh
Not sure why the ./ and not color.sh directly. The content of color.sh is as follows.
RED=`tput setaf 1`
GREEN=`tput setaf 2`
BLUE=`tput setaf 4`
BOLD=`tput bold`
RESET=`tput sgr0`
Making use of File color.sh does not error but, the color do not display. I have tested this in Ubuntu 18.04 and the Bash version is:
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)

Resources