如何拆分$ 0变量以在bash中查找目录和相对路径?


10

$ 0变量包含脚本的路径信息。

  • 如何将路径信息更改为绝对路径?我的意思是如何处理〜,...或类似的东西?
  • 如何将路径信息分为目录和文件名?

我可以为此使用python / perl,但如果可能的话,我想使用bash。


您想达到什么目的?顺便说一句 使用我的bash版本(GNU bash,版本4.1.5(2)-release-(x86_64-unknown-linux-gnu))用〜/ foo.sh调用脚本将扩展〜进入我的主目录,价格为$ 0
echox

Answers:


17

您不需要处理诸如~shell之类的事情。这就是为什么您可以传递~/filename给任何脚本或程序并且可以正常工作的原因-所有这些程序都不自行处理~,您的shell将参数转换为/home/username/filename并将其传递给程序:

$ echo ~/filename
/home/mrozekma/filename

如果您需要一个规范的文件名(其中不包含..),请使用realpath(感谢Neil):

$ realpath ~/../filename
/home/filename

至于将路径分为目录名和文件名,请使用dirnamebasename

$ dirname /foo/bar/baz
/foo/bar

$ basename /foo/bar/baz
baz

我认为您的意思是realpath,而不是readlink。readlink在通常情况下不起作用,即,当链接使用相对路径并且您与链接不在同一个目录中时。
尼尔·梅休

@Neil realpath更好,但是readlink当我尝试它时似乎可以工作;您知道失败的例子吗?
Michael Mrozek

1
cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar。这将返回foorealpath返回/tmp/foo,这就是您想要的。
尼尔·梅休

1
@Neil,@Michael:readlink -f(note -f)几乎等同于realpath,并且更具可移植性:readlink -f在GNU coreutils中,也存在于其他一些系统上;realpath单独包装,可能无法安装(例如,在Ubuntu 10.04或Debian lenny中仅依赖5个非常见包装)。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

@吉尔斯:很好。感谢您提醒有关realpath -f。
尼尔·梅

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中最长的部分。

像一些正则表达式和###某种贪婪/非贪婪修饰符一样看待模式。

如果您必须对路径部分进行一些更复杂的提取,这可能会很有用。


5
使用时要小心${...##...}和朋友,而不是dirnamebasename他们不适用于所有情况。例如两者${0##*/}${0%/*}扩大到一样$0,如果$0不包含/
吉尔斯(Gillles)“所以-别再邪恶了”,2010年

我知道@Gilles为什么${0%/*}不是一个很好的选择dirname。但是,使用${0##*/}代替代替有basename什么问题?
toxalot

@toxalot对于此问题,唯一的问题是when $0是带有尾随的目录名称/。但是我后悔我的建议,因为dirname情况没有任何改善。
吉尔斯(Gilles)'“ SO-不要邪恶”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.