Answers:
您不需要处理诸如~shell之类的事情。这就是为什么您可以传递~/filename给任何脚本或程序并且可以正常工作的原因-所有这些程序都不自行处理~,您的shell将参数转换为/home/username/filename并将其传递给程序:
$ echo ~/filename
/home/mrozekma/filename如果您需要一个规范的文件名(其中不包含..),请使用realpath(感谢Neil):
$ realpath ~/../filename
/home/filename至于将路径分为目录名和文件名,请使用dirname和basename:
$ dirname /foo/bar/baz
/foo/bar
$ basename /foo/bar/baz
bazrealpath更好,但是readlink当我尝试它时似乎可以工作;您知道失败的例子吗?
                    cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar。这将返回foo并realpath返回/tmp/foo,这就是您想要的。
                    readlink -f(note -f)几乎等同于realpath,并且更具可移植性:readlink -f在GNU coreutils中,也存在于其他一些系统上;realpath单独包装,可能无法安装(例如,在Ubuntu 10.04或Debian lenny中仅依赖5个非常见包装)。
                    使用Michael提到的dirname和basename应该是获得所需内容的最安全方法。
无论如何,如果您真的想使用“仅打击工具”来执行此操作,则可以使用参数替换:
echo `basename $PWD`        # Basename of current working directory.
echo "${PWD##*/}"           # Basename of current working directory.
echo
echo `basename $0`          # Name of script.
echo $0                     # Name of script.
echo "${0##*/}"             # Name of script.
echo
filename=test.data
echo "${filename##*.}"      # data
                            # Extension of filename.该示例直接取自《高级Bash脚本指南》,值得一看。
解释很简单:
$ {var#Pattern}从$ var中删除与$ var前端匹配的$ Pattern最短部分。$ {var ## Pattern}从$ var中删除与$ var前端匹配的$ Pattern中最长的部分。
像一些正则表达式和#或##某种贪婪/非贪婪修饰符一样看待模式。
如果您必须对路径部分进行一些更复杂的提取,这可能会很有用。
${...##...}和朋友,而不是dirname和basename他们不适用于所有情况。例如两者${0##*/}并${0%/*}扩大到一样$0,如果$0不包含/。
                    ${0%/*}不是一个很好的选择dirname。但是,使用${0##*/}代替代替有basename什么问题?
                    $0是带有尾随的目录名称/。但是我后悔我的建议,因为dirname情况没有任何改善。
                    realpath 是一个告诉您实际路径的命令(删除..和符号链接等)
这是FreeBSD的标准配置。根据此讨论,它也可用于Linux:
http://www.unix.com/shell-programming-scripting/89294-geting-real-path.html
该讨论还提供了一个bash解决方案:
$ bash -c "cd /foo/../bar/ ; pwd"