Macos 获取OS X shell脚本位于脚本中的路径…当路径包含空格时

Macos 获取OS X shell脚本位于脚本中的路径…当路径包含空格时,macos,bash,Macos,Bash,我在Bash脚本中使用它来获取运行脚本的路径。双击OSX中的.command文件是必需的 #!/bin/bash BASEDIR=$(dirname $0) cd $BASEDIR #!/bin/bash BASEDIR=$(dirname $0) cd "$BASEDIR" 问题是当路径有空间时,它不起作用。如何解决这个问题?您必须使用引号: 我用它来启动plackup服务器,我的:“run.command” 这可能是一场灾难。前面的答案都无法解析符号链接。 这一个应该是可移植的(使用破折

我在Bash脚本中使用它来获取运行脚本的路径。双击OSX中的.command文件是必需的

#!/bin/bash
BASEDIR=$(dirname $0)
cd $BASEDIR
#!/bin/bash
BASEDIR=$(dirname $0)
cd "$BASEDIR"

问题是当路径有空间时,它不起作用。如何解决这个问题?

您必须使用引号:


我用它来启动plackup服务器,我的:“run.command”


这可能是一场灾难。前面的答案都无法解析符号链接。 这一个应该是可移植的(使用破折号和bash进行双重检查),并将遍历路径中带有空格的符号链接:


仍然不起作用,问题在于dirname:usage:dirname路径检查$PWD是否与$0路径匹配。这可能会在BaseDirName中产生空结果。您还需要在$0组件周围加引号,以便它作为单个参数而不是多个参数呈现给dirname。您需要在任何内容周围加引号,以防止包含空格的变量出现附带问题。。请参阅此答案检查。
#!/bin/bash
BASEDIR="$( dirname "$0" )"
cd "$BASEDIR"
DIR=`dirname "$0"`
cd "$DIR"
plackup -r
#!/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'.

##===-------------------------------------------------------------------===##

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;  then
    errnoent 1>&2; exit 1; elif [ ! -e "$@" -a "$link" = "$@" ];   then
    recurses 1>&2; exit 1; elif [ ! -e "$@" ] && [ ! -z "$link" ]; then
    dangling 1>&2; exit 1; fi
 fi

## Not a link, but there might be one in the path, so 'cd' and 'pwd'.

 if [ -z "$link" ]; then if [ "$(dirname "$@" | cut -c1)" = '/' ]; then
   printf "$@\n"; exit 0; else printf "$(pwd)/$(basename "$@")\n"; fi; exit 0
 fi

## Walk the symlinks back to the origin. Calls itself recursivly as needed.

 while [ "$link" ]; do
   cd "$(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"                           ;;
   esac
 done
 printf "$(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