/usr/bin/cd 是什么鬼
上文中曾讲到,我在我的 Mac 上发现很多和 Bash 内部命令同名的外部命令,在那 24 个外部命令中,我发现个奇怪的现象:它们中有 15 个居然是 Shell 脚本,更奇怪的是,居然是同一个 Shell 脚本的硬链接:
$ find /usr/bin -inum 376183 /usr/bin/alias /usr/bin/bg /usr/bin/cd /usr/bin/command /usr/bin/fc /usr/bin/fg /usr/bin/getopts /usr/bin/hash /usr/bin/jobs /usr/bin/read /usr/bin/type /usr/bin/ulimit /usr/bin/umask /usr/bin/unalias /usr/bin/wait |
看看脚本的内容:
$ cat /usr/bin/cd #!/bin/sh # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $ # This file is in the public domain. builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"} |
脚本只有一行,它的作用是什么?我分析了一下,当用户正常输入一个内部命令比如说 cd 时,Shell 肯定会把它当成内部命令执行,只有用户不小心把 cd 输入成 CD,由于 Mac 的文件系统不区分大小写,Shell 才会去执行这个外部的脚本。这个脚本拿到 $0 的值,也就是 /usr/bin/CD,砍掉路径,然后把大小字母替换成小写,也就是 cd,然后去执行 cd,同时带上参数。但我有几点想不通,这里的 builtin 完全是多余的,${1+"$@"} 也完全可以简写成 "$@",最重要的是,执行这些脚本是几乎没有任何意义的,因为 Shell 脚本是在当前 Shell 进程的新起的 Shell 进程里执行的,也就是说执行 CD / 相当于执行 bash -c 'cd /',当前 Shell 的工作目录其实并没有改变,除了 cd,其他命令也一样,虽然执行了,但完全没用,我再用 alias 和 unalias 演示一下:
$ alias 'll=ls -l' $ Alias $ Unalias ll /usr/bin/Unalias: line 4: unalias: ll: not found $ alias alias ll='ls -l' |
这么做的出发点是什么,输入 CD 应该报错才对啊,不报错反而执行了没效果,多让人困惑的行为。
于是我在网上查了一下,发现一篇日语的文章详详细细的介绍了这个脚本的来龙去脉。原来这个脚本存在的原因是:POSIX 标准要求操作系统要提供这 14 个内部命令对应的外部命令,以便 env、find、nice、nohup、time、xargs 这几个外部命令调用,比如 env cd。POSIX 又为什么这么规定,那就不知道了,但的确没卵用啊,怪不得 Linux 就没有遵守这个规范。
最初这个脚本诞生于 FreeBSD 上,为什么加上 builtin 和用 ${1+"$@"} 都是因为 FreeBSD 操作系统的原因,那篇文章有讲。还有最初的脚本是没有 tr \[:upper:] \[:lower:] 这一部分的,FreeBSD 上不需要这个,苹果移植的时候考虑到自己的文件系统不区分大小写,故意做了改良。
/usr/bin/cd 是什么鬼的更多相关文章
- linux /usr/bin/ld cannot find 解决
问题: 在linux环境编译应用程式或lib的source code时常常会出现如下的错误讯息: /usr/bin/ld: cannot find -lxxx 这些讯息会随着编译不同类型的source ...
- linux /usr/bin/ld: cannot find -lxxx
在linux环境编译应用程式或lib的source code时出现如下错误:/usr/bin/ld: cannot find -lxxx 这些讯息会随着编译不同类型的source code 而有不同的 ...
- 关于usr/bin/ld: cannot find -lxxx问题总结
/usr/bin/ld: cannot find -lxxx问题总结 linux下编译应用程序常常会出现如下错误: /usr/bin/ld: cannot find -lxxx ...
- innobackupex:Error:xtrabackup child process has died at /usr/bin/innobackupex
使用innobackupex进行数据库备份,报如下错误:innobackupex --compress --parallel=4 --user=root --password=yoon /expo ...
- 【转】关于usr/bin/ld: cannot find -lxxx问题总结
原文网址:http://eminzhang.blog.51cto.com/5292425/1285705 /usr/bin/ld: cannot find -lxxx问题总结 linux下编译应用 ...
- 【转】linux /usr/bin/ld cannot find 解决
原文网址:http://blog.csdn.net/mzwang123/article/details/6702889 问题:在linux环境编译应用程式或lib的source code时常常会出现如 ...
- make报错:"/usr/bin/ld: cannot find -lXXX"
在编译php时报错如下: # make ... /usr/bin/ld: cannot find -lltdlcollect2: ld returned 1 exit statusmake: *** ...
- cuda8.0 /usr/bin/ld: cannot find -lGL
/usr/bin/ld: cannot find -lGL collect2: ld returned 1 exit status tennycent@tennycent-desktop:~/$ ...
- (转载)关于usr/bin/ld: cannot find -lxxx问题总结
usr/bin/ld: cannot find -lxxx问题总结 linux下编译应用程序常常会出现如下错误: /usr/bin/ld: cannot find -lxxx 意思是 ...
随机推荐
- 【小白的CFD之旅】03 老蓝
第一次见到老蓝,小白都不太敢相信,对面那不修边幅的糟老头子会是自己要找的导师.嘴里叼着烟,牙都掉了好几颗,穿着还算整齐,这是小白对老蓝的第一印象,这印象并不太好,尤其是在小白发誓认真度过研究生三年时光 ...
- 帆软报表FineReport中数据连接之Weblogic配置JNDI连接
1. 制作报表的原理 在帆软报表FineReport设计器中先用JDBC连接到数据库,建立数据库连接,然后用SQL或者其他方法创建数据集,使用数据集制作报表,然后把建立的数据库连接从JDBC连接改成J ...
- Neutron 理解 (8): Neutron 是如何实现虚机防火墙的 [How Neutron Implements Security Group]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
- es6学习笔记1 --let以及const
let语句的基本用法: 1.let声明的变量为块级作用域,只在最近的{}里面有效,如果在外部引用就会报错. { let a = 10; var b = "hello" } ale ...
- oracle 错误代码大全
oracle错误代码大全(超详细) ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最 ...
- POJ2828 Buy Tickets[树状数组第k小值 倒序]
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 19012 Accepted: 9442 Desc ...
- 由于log太多导致ubuntu硬盘空间满了,进入不了系统解决办法
具体现象是在图形界面输入用户名和密码之后,再次提示需要输入用户名和密码. 步骤一:按快捷键进入命令行界面.ctrl+alt+f1. 步骤二:清空文件 clear log cd /var/log sud ...
- Laravel五大功能之Eloquent关系模式
Eloquent是Laravel的原始ActiveRecord是实现的,建立在Laravel的Fluent Query Builder之上的,所以Eloquent类和Fluent类是一样的,能实现复杂 ...
- C语言实现线程池
以前写过一篇关于如何使用多线程推升推送速度(http://www.cnblogs.com/bai-jimmy/p/5177433.html),能够到达5000qps,其实已经可以满足现在的业务,不过在 ...
- java多线程系类:JUC线程池:04之线程池原理(三)(转)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--"基础篇& ...