#!/usr/bin/env bash
echo "The script you are running has basename $( basename -- "$0"; ), dirname $( dirname -- "$0"; )";echo "The present working directory is $( pwd; )";
如果您没有从包含它的目录运行脚本,单独使用pwd将无法工作。
[matt@server1 ~]$ pwd/home/matt[matt@server1 ~]$ ./test2.shThe script you are running has basename test2.sh, dirname .The present working directory is /home/matt[matt@server1 ~]$ cd /tmp[matt@server1 tmp]$ ~/test2.shThe script you are running has basename test2.sh, dirname /home/mattThe present working directory is /tmp
#!/usr/bin/env bash
SOURCE=${BASH_SOURCE[0]}while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlinkDIR=$( 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 locateddoneDIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
#!/usr/bin/env bash
SOURCE=${BASH_SOURCE[0]}while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlinkTARGET=$(readlink "$SOURCE")if [[ $TARGET == /* ]]; thenecho "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"SOURCE=$TARGETelseDIR=$( 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 locatedfidoneecho "SOURCE is '$SOURCE'"RDIR=$( dirname "$SOURCE" )DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )if [ "$DIR" != "$RDIR" ]; thenecho "DIR '$RDIR' resolves to '$DIR'"fiecho "DIR is '$DIR'"
它将打印如下内容:
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'
function getScriptAbsoluteDir { # fold>># @description used to get the script path# @param $1 the script $0 parameterlocal script_invoke_path="$1"local cwd=`pwd`
# absolute path ? if so, the first character is a /if test "x${script_invoke_path:0:1}" = 'x/'thenRESULT=`dirname "$script_invoke_path"`elseRESULT=`dirname "$cwd/$script_invoke_path"`fi} # <<fold
# Retrieve the full pathname of the called scriptscriptPath=$(which $0)
# Check whether the path is a link or notif [ -L $scriptPath ]; then
# It is a link then retrieve the target path and get the directory namesourceDir=$(dirname $(readlink -f $scriptPath))
else
# Otherwise just get the directory name of the script pathsourceDir=$(dirname $scriptPath)
fi
function get_realpath() {
if [[ -f "$1" ]]then# The file *must* existif cd "$(echo "${1%/*}")" &>/dev/nullthen# The file *may* not be local.# The exception is ./file.ext# tTry 'cd .; cd -;' *works!*local tmppwd="$PWD"cd - &>/dev/nullelse# file *must* be locallocal tmppwd="$PWD"fielse# The file *cannot* existreturn 1 # Failurefi
# Reassemble realpathecho "$tmppwd"/"${1##*/}"return 0 # Success
}
function get_dirname(){
local realpath="$(get_realpath "$1")"if (( $? )) # True when non-zero.thenreturn $? # Failurefiecho "${realpath%/*}"return 0 # Success
}
# Then from the top level:get_dirname './script.sh'
# Or within a script:get_dirname "$0"
# Can even test the outcome!if (( $? )) # True when non-zero.thenexit 1 # Failurefi
#!/bin/sh # dash bash ksh # !zsh (issues). G. Nixon, 12/2013. Public domain.
## 'linkread' or 'fullpath' or (you choose) is a little tool to recursively## dereference symbolic links (ala 'readlink') until the originating file## is found. This is effectively the same function provided in stdlib.h as## 'realpath' and on the command line in GNU 'readlink -f'.
## Neither of these tools, however, are particularly accessible on the many## systems that do not have the GNU implementation of readlink, nor ship## with a system compiler (not to mention the requisite knowledge of C).
## This script is written with portability and (to the extent possible, speed)## in mind, hence the use of printf for echo and case statements where they## can be substituded for test, though I've had to scale back a bit on that.
## It is (to the best of my knowledge) written in standard POSIX shell, and## has been tested with bash-as-bin-sh, dash, and ksh93. zsh seems to have## issues with it, though I'm not sure why; so probably best to avoid for now.
## Particularly useful (in fact, the reason I wrote this) is the fact that## it can be used within a shell script to find the path of the script itself.## (I am sure the shell knows this already; but most likely for the sake of## security it is not made readily available. The implementation of "$0"## specificies that the $0 must be the location of **last** symbolic link in## a chain, or wherever it resides in the path.) This can be used for some## ...interesting things, like self-duplicating and self-modifiying scripts.
## Currently supported are three errors: whether the file specified exists## (ala ENOENT), whether its target exists/is accessible; and the special## case of when a sybolic link references itself "foo -> foo": a common error## for beginners, since 'ln' does not produce an error if the order of link## and target are reversed on the command line. (See POSIX signal ELOOP.)
## It would probably be rather simple to write to use this as a basis for## a pure shell implementation of the 'symlinks' util included with Linux.
## As an aside, the amount of code below **completely** belies the amount## effort it took to get this right -- but I guess that's coding for you.
##===-------------------------------------------------------------------===##
for argv; do :; done # Last parameter on command line, for options parsing.
## Error messages. Use functions so that we can sub in when the error occurs.
recurses(){ printf "Self-referential:\n\t$argv ->\n\t$argv\n" ;}dangling(){ printf "Broken symlink:\n\t$argv ->\n\t"$(readlink "$argv")"\n" ;}errnoent(){ printf "No such file: "$@"\n" ;} # Borrow a horrible signal name.
# Probably best not to install as 'pathfull', if you can avoid it.
pathfull(){ cd "$(dirname "$@")"; link="$(readlink "$(basename "$@")")"
## 'test and 'ls' report different status for bad symlinks, so we use this.
if [ ! -e "$@" ]; then if $(ls -d "$@" 2>/dev/null) 2>/dev/null; thenerrnoent 1>&2; exit 1; elif [ ! -e "$@" -a "$link" = "$@" ]; thenrecurses 1>&2; exit 1; elif [ ! -e "$@" ] && [ ! -z "$link" ]; thendangling 1>&2; exit 1; fifi
## Not a link, but there might be one in the path, so 'cd' and 'pwd'.
if [ -z "$link" ]; then if [ "$(dirname "$@" | cut -c1)" = '/' ]; thenprintf "$@\n"; exit 0; else printf "$(pwd)/$(basename "$@")\n"; fi; exit 0fi
## Walk the symlinks back to the origin. Calls itself recursivly as needed.
while [ "$link" ]; docd "$(dirname "$link")"; newlink="$(readlink "$(basename "$link")")"case "$newlink" in"$link") dangling 1>&2 && exit 1 ;;'') printf "$(pwd)/$(basename "$link")\n"; exit 0 ;;*) link="$newlink" && pathfull "$link" ;;esacdoneprintf "$(pwd)/$(basename "$newlink")\n"}
## Demo. Install somewhere deep in the filesystem, then symlink somewhere## else, symlink again (maybe with a different name) elsewhere, and link## back into the directory you started in (or something.) The absolute path## of the script will always be reported in the usage, along with "$0".
if [ -z "$argv" ]; then scriptname="$(pathfull "$0")"
# Yay ANSI l33t codes! Fancy.printf "\n\033[3mfrom/as: \033[4m$0\033[0m\n\n\033[1mUSAGE:\033[0m "printf "\033[4m$scriptname\033[24m [ link | file | dir ]\n\n "printf "Recursive readlink for the authoritative file, symlink after "printf "symlink.\n\n\n \033[4m$scriptname\033[24m\n\n "printf " From within an invocation of a script, locate the script's "printf "own file\n (no matter where it has been linked or "printf "from where it is being called).\n\n"
else pathfull "$@"fi
#!/bin/sh(path="${0}"while test -n "${path}"; do# Make sure we have at least one slash and no leading dash.expr "${path}" : / > /dev/null || path="./${path}"# Filter out bad characters in the path name.expr "${path}" : ".*[*?<>\\]" > /dev/null && exit 1# Catch embedded new-lines and non-existing (or path-relative) files.# $0 should always be absolute when scripts are invoked through "#!".test "`ls -l -d "${path}" 2> /dev/null | wc -l`" -eq 1 || exit 1# Change to the folder containing the file to resolve relative links.folder=`expr "${path}" : "\(.*/\)[^/][^/]*/*$"` || exit 1path=`expr "x\`ls -l -d "${path}"\`" : "[^>]* -> \(.*\)"`cd "${folder}"# If the last path was not a link then we are in the target folder.test -n "${path}" || pwddone)
#!/usr/bin/env sh
dir=$(cd "${0%[/\\]*}" > /dev/null && pwd)
if [ -d /proc/cygdrive ]; thencase "$(uname -s)" inCYGWIN*|MINGW32*|MSYS*|MINGW*)# We are under Windows, so translate path to Windows format.dir=$(cygpath -m "$dir");;;esacfi
# Runs the executable which is beside this script"${dir}/my-sample-app" "$@"
function include(){if [[ -n "$CURRENT_SCRIPT_DIR" ]]; thenlocal dir_path=... get directory from `CURRENT_SCRIPT_DIR/$1`, depends if $1 is absolute path or relative ...local include_file_path=...elselocal dir_path=... request the directory from the "$1" argument using one of answered here methods...local include_file_path=...fi... push $CURRENT_SCRIPT_DIR in to stack ...export CURRENT_SCRIPT_DIR=... export current script directory using $dir_path ...source "$include_file_path"... pop $CURRENT_SCRIPT_DIR from stack ...}
#!/bin/sh
# Get an absolute path for the poem.txt file.POEM="$PWD/../poem.txt"
# Get an absolute path for the script file.SCRIPT="$(which $0)"if [ "x$(echo $SCRIPT | grep '^\/')" = "x" ] ; thenSCRIPT="$PWD/$SCRIPT"fi
## BASE BRAIN - Get where you're from and who you are.MYPID=$$ORIGINAL_DIR="$(pwd)" # This is not a hot air balloon ride..fa="$0" # First Assumptionta= # Temporary Assumptionwa= # Weighed Assumptionwhile true; do[ "${fa:0:1}" = "/" ] && wa=$0 && break[ "${fa:0:2}" = "./" ] && ta="${ORIGINAL_DIR}/${fa:2}" && [ -e "$ta" ] && wa="$ta" && breakta="${ORIGINAL_DIR}/${fa}" && [ -e "$ta" ] && wa="$ta" && breakdoneSW="$wa"SWDIR="$(dirname "$wa")"SWBIN="$(basename "$wa")"unset ta fa wa( [ ! -e "$SWDIR/$SWBIN" ] || [ -z "$SW" ] ) && echo "I could not find my way around :( possible bug in the TOP script" && exit 1
FULL_PATH_TO_SCRIPT="$(realpath "${BASH_SOURCE[-1]}")"
# OR, if you do NOT need it to work for **sourced** scripts too:# FULL_PATH_TO_SCRIPT="$(realpath "$0")"
# OR, depending on which path you want, in case of nested `source` calls# FULL_PATH_TO_SCRIPT="$(realpath "${BASH_SOURCE[0]}")"
# OR, add `-s` to NOT expand symlinks in the path:# FULL_PATH_TO_SCRIPT="$(realpath -s "${BASH_SOURCE[-1]}")"
SCRIPT_DIRECTORY="$(dirname "$FULL_PATH_TO_SCRIPT")"SCRIPT_FILENAME="$(basename "$FULL_PATH_TO_SCRIPT")"
#!/bin/bash
# A. Obtain the full path, and expand (walk down) symbolic links# A.1. `"$0"` works only if the file is **run**, but NOT if it is **sourced**.# FULL_PATH_TO_SCRIPT="$(realpath "$0")"# A.2. `"${BASH_SOURCE[-1]}"` works whether the file is sourced OR run, and even# if the script is called from within another bash function!# NB: if `"${BASH_SOURCE[-1]}"` doesn't give you quite what you want, use# `"${BASH_SOURCE[0]}"` instead in order to get the first element from the array.FULL_PATH_TO_SCRIPT="$(realpath "${BASH_SOURCE[-1]}")"# B.1. `"$0"` works only if the file is **run**, but NOT if it is **sourced**.# FULL_PATH_TO_SCRIPT_KEEP_SYMLINKS="$(realpath -s "$0")"# B.2. `"${BASH_SOURCE[-1]}"` works whether the file is sourced OR run, and even# if the script is called from within another bash function!# NB: if `"${BASH_SOURCE[-1]}"` doesn't give you quite what you want, use# `"${BASH_SOURCE[0]}"` instead in order to get the first element from the array.FULL_PATH_TO_SCRIPT_KEEP_SYMLINKS="$(realpath -s "${BASH_SOURCE[-1]}")"
# You can then also get the full path to the directory, and the base# filename, like this:SCRIPT_DIRECTORY="$(dirname "$FULL_PATH_TO_SCRIPT")"SCRIPT_FILENAME="$(basename "$FULL_PATH_TO_SCRIPT")"
# Now print it all outecho "FULL_PATH_TO_SCRIPT = \"$FULL_PATH_TO_SCRIPT\""echo "SCRIPT_DIRECTORY = \"$SCRIPT_DIRECTORY\""echo "SCRIPT_FILENAME = \"$SCRIPT_FILENAME\""
# Obtain the full path, but do NOT expand (walk down) symbolic links; in# other words: **keep** the symlinks as part of the path!FULL_PATH_TO_SCRIPT="$(realpath -s "${BASH_SOURCE[-1]}")"