How to determine the internal script itself Bash script file name?
Like my script file runme.sh
, then I how to without hard-coding the display "You are running runme.sh" news?
#1st Floor
this="$(dirname "$(realpath "$BASH_SOURCE")")"
This will resolve the case of a symbolic link (realpath can be done), can handle spaces (use double quotes can do this), or other scripts call ($ BASH_SOURCE can handle) even in the source code (../myscript) of , you can also find the current script name. After all, it is best to save it in an environment variable for re-use or easily replicated elsewhere (this =) ...
#2nd Floor
me=`basename "$0"`
To read the symbolic link is usually not what you want 1 (so that you typically do not want to confuse the user), try:
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
IMO, which will produce confusing output. "I ran foo.sh, but this is to say I am running bar.sh!? Must be a bug!" In addition, one of the symbols of links with different names purpose is to provide different functions according to its name (in some the platform can think about gzip and gunzip).
1 In other words, to resolve a symbolic link, so that when the user performs foo.sh
(actually bar.sh
symbolic links), you want to use name resolution bar.sh
insteadfoo.sh
#3rd floor
echo "You are running $ 0"
#4th floor
You can use $ 0 to determine the script name (with full path) - Get the name of the script only, you can use
basename $0
#5th Floor
If the script name contains spaces, is more robust approach is to use "$0"
or "$(basename "$0")"
- or used on MacOS "$(basename \\"$0\\")"
. This prevents confusion or in any way explain the name. In general, a good practice is to always shell in double quotes.
#6th floor
$0
Not answer the question (as I understand). Demo:
$ cat script.sh #! /bin/sh echo `basename $0` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript
How do I get ./linktoscript
to print out script.sh
?
[Edit] In the above comment, although @ephemient seems to be fictional, but may still be tinkering with $0
it does not mean that the file system resources. OP bit vague for the content he wants.
#7th floor
To answer Chris Conway , at least in Linux on, you can do this:
echo $(basename $(readlink -nf $0))
readlink prints out the value of the symbolic link. If it is not a symbolic link, then print the file name. -n tells it does not print a newline. -f tells it to follow the link completely (if a symbolic link is a link to another link, then the link will be resolved).
Building # 8
If you want it there is no path, you can use${0##*/}
House # 9
I found this trip is always valid, regardless of the source file or script file is run as.
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
If you want to follow symbolic links, use recursively or non-recursively in the path of your arrival readlink
.
By using BASH_SOURCE
environment variables and their association FUNCNAME
to explain the work of a single line.
BASH_SOURCE
An array variable whose members are the source file name, which is defined in the housing corresponding function names FUNCNAME array variable. Housing function $ {FUNCNAME [$ i]} in the file $ {BASH_SOURCE [$ i]} is defined, and from $ {BASH_SOURCE [$ i + 1]} call.
function name
An array variable containing all currently in the execution call stack shell name of the function. Index element 0 is the name of any Shell function currently being performed. The bottom elements (elements with the highest index) is "main". Only when performing the Shell function, this variable only exists. Assigned to FUNCNAME invalid, and returns an error status. If FUNCNAME not set, even if subsequently reset, it will lose its special properties.
This variable can be used with BASH_LINENO and BASH_SOURCE. Each element in FUNCNAME BASH_SOURCE BASH_LINENO and have corresponding elements described in the call stack. For example, from the document $ {BASH_SOURCE [$ i + 1]} row number $ {BASH_LINENO [$ i]} is called at $ {FUNCNAME [$ i]}. Built caller use this information to display the current call stack.
[Source: Bash manual]
#10th floor
Information thanks to Bill Hernandez. I added some preferences adopted.
#!/bin/bash
function Usage(){
echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me ---------------> ${0} " | sed "s/$USER/\$USER/g"
echo "# parent path --------------> ${0%/*} " | sed "s/$USER/\$USER/g"
echo "# my name ------------------> ${0##*/} "
echo
}
Cheers
House # 11
Such a thing?
export LC_ALL=en_US.UTF-8
#!/bin/bash
#!/bin/sh
#----------------------------------------------------------------------
start_trash(){
ver="htrash.sh v0.0.4"
$TRASH_DIR # url to trash $MY_USER
$TRASH_SIZE # Show Trash Folder Size
echo "Would you like to empty Trash [y/n]?"
read ans
if [ $ans = y -o $ans = Y -o $ans = yes -o $ans = Yes -o $ans = YES ]
then
echo "'yes'"
cd $TRASH_DIR && $EMPTY_TRASH
fi
if [ $ans = n -o $ans = N -o $ans = no -o $ans = No -o $ans = NO ]
then
echo "'no'"
fi
return $TRUE
}
#-----------------------------------------------------------------------
start_help(){
echo "HELP COMMANDS-----------------------------"
echo "htest www open a homepage "
echo "htest trash empty trash "
return $TRUE
} #end Help
#-----------------------------------------------#
homepage=""
return $TRUE
} #end cpdebtemp
# -Case start
# if no command line arg given
# set val to Unknown
if [ -z $1 ]
then
val="*** Unknown ***"
elif [ -n $1 ]
then
# otherwise make first arg as val
val=$1
fi
# use case statement to make decision for rental
case $val in
"trash") start_trash ;;
"help") start_help ;;
"www") firefox $homepage ;;
*) echo "Sorry, I can not get a $val for you!";;
esac
# Case stop
House # 12
# ------------- SCRIPT ------------- #
#!/bin/bash
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 ----------------------> $1 "
echo "# \$2 ----------------------> $2 "
echo "# path to me ---------------> ${0} "
echo "# parent path --------------> ${0%/*} "
echo "# my name ------------------> ${0##*/} "
echo
exit
# ------------- CALLED ------------- #
# Notice on the next line, the first argument is called within double,
# and single quotes, since it contains two words$ /misc/shell_scripts/check_root/show_parms.sh "'hello there'" "'william'"
# ------------- RESULTS ------------- #
# arguments called with ---> 'hello there' 'william'
# $1 ----------------------> 'hello there'
# $2 ----------------------> 'william'
# path to me --------------> /misc/shell_scripts/check_root/show_parms.sh
# parent path -------------> /misc/shell_scripts/check_root
# my name -----------------> show_parms.sh is the
# ------------- ------------- END of #
House # 13
Re: The above Tanktalus (have accepted) answer, a more simple approach is to use:
me=$(readlink --canonicalize --no-newline $0)
If your bash script from another script, you can use:
me=$(readlink --canonicalize --no-newline $BASH_SOURCE)
I agree, if your goal is to provide feedback to the user, the dereference symbolic links confusing, but sometimes you do need to get to the canonical name of a script or other document, which is the best way imo.
House # 14
If you like to call shell script
/home/mike/runme.sh
$ 0 is the full name
/home/mike/runme.sh
basename $ 0 to get the base filename
runme.sh
And you need to put this base name similar variables
filename=$(basename $0)
And add other text
echo "You are running $filename"
So your script is like
/home/mike/runme.sh
#!/bin/bash
filename=$(basename $0)
echo "You are running $filename"
House # 15
echo "$(basename "`test -L ${BASH_SOURCE[0]} \
&& readlink ${BASH_SOURCE[0]} \
|| echo ${BASH_SOURCE[0]}`")"
House # 16
In bash
that you can use $0
to get the script file name. Generally $1
, $2
and other parameters used to access the CLI. Similarly, $0
for accessing trigger name of the script (script file name).
#!/bin/bash
echo "You are running $0"
...
...
If you /path/to/script.sh
like /path/to/script.sh
to call script, $0
it will also provide a file name with the path. In this case, you need $(basename $0)
to obtain only the script file name.
House # 17
Because some of the comments questioned the file name without the extension, therefore, the following is an example that shows how to do this:
FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}
Please enjoy!
House # 18
This is what I based on Dimitre Radoulov answer (by the way, I agree with) the inspiration come in.
script="$BASH_SOURCE"
[ -z "$BASH_SOURCE" ] && script="$0"
echo "Called $script with $# argument(s)"
No matter how you call the script
. path/to/script.sh
Or
./path/to/script.sh
House # 19
In my_script.sh
brief, clear and simple
#!/bin/bash
running_file_name=$(basename "$0")
echo "You are running '$running_file_name' file."
Output:
./my_script.sh
You are running 'my_script.sh' file.
House # 20
DIRECTORY=$(cd `dirname $0` && pwd)
I'm from another stack overflow problem has been the above, a Bash script can tell it is stored in the directory in which to do? , But I think it is also useful for this topic.
House # 21
In the procurement of the script, $BASH_SOURCE
provide the correct answer.
However, this includes the path, and therefore get only the script file name, use:
$(basename $BASH_SOURCE)
House # 22
The answer to the stated conditions are right, but if you use the 'source' key to run the script from another script (so that it runs in the same housing), the problem still exists. In this case, you will get to call the script $ 0. In this case, I think it can not get the name of the script itself.
This is an extreme case, it should not take it too seriously. If directly from another script (without the "source") to run the script, you can use $ 0.
House # 23
Use bash> = 3 when , following work effectively:
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"