May*_*nty 5 macos bash freebsd
我正在编写一些代码,通过命令行浏览我的计算机(OSX 10.11.6),就像我一直这样,我写错了!(Bum-Bum-BUUUUM!)而不是输入:
cd USB
Run Code Online (Sandbox Code Playgroud)
我打字了
Cd USB
Run Code Online (Sandbox Code Playgroud)
什么都没发生,但它没有注册为无效命令.对此感到困惑,我做了一些调查:我检查了man
条目.没有入场券.我发现源文件(/usr/bin/Cd
)使用which Cd
,然后cat
编辑它:
#!/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+"$@"}
Run Code Online (Sandbox Code Playgroud)
这是什么,为什么会在这里?它与freeBSD有什么关系?
任何帮助都会很棒,谢谢!
默认情况下, macOS使用不区分大小写的文件系统[1] ,这有时会产生误导:
which Cd
是有效相同which cd
并which CD
在返回(有效地)相同的文件路径的条款.
令人困惑的是,即使所有3个命令都引用同一个文件,它们也会以保持大小写的方式执行此操作,误导性地表明文件名的实际情况是您指定的任何内容.
作为一种解决方法,如果使用globbing(文件名扩展),则可以看到文件名的真实情况:
$ ls "$(which Cd)"* # could match additional files, but the one of interest is among them
/usr/bin/cd # true case of the filename
Run Code Online (Sandbox Code Playgroud)
Bash(macOS默认shell)在内部区分大小写.也就是说,它识别cd
为builtincd
(其内置的目录更改命令).
相比之下,由于案例的不同,它不承认Cd
这一点.
鉴于它不能识别Cd
为内置函数,它会寻找一个外部实用程序(在$PATH
)中,就在它找到时/usr/bin/cd
.
/usr/bin/cd
实现为shell脚本,这通常是无用的,因为作为外部实用程序它不会影响shell的状态,因此它只是静静地忽略了它更改目录的尝试.
(Keith Thompson在评论中指出,您可以使用它作为测试是否可以更改给定目录,因为脚本的退出代码将反映出来).
Matt的回答提供了将脚本包含在FreeBSD和OSX中的历史(主要基于FreeBSD),但值得仔细研究一下这个理由(强调我的):
从POSIX规范:
但是,所有标准实用程序,包括表中的常规内置函数,而不是特殊内置实用程序中描述的特殊内置函数,都应以某种方式实现,以便可以通过exec系列访问它们.函数在POSIX.1-2008的系统接口卷中定义,并且可以由需要它的那些标准实用程序直接调用(env,find,nice,nohup,time,xargs).
从本质上讲,上述意思是:常规内置函数必须(也)可以独立调用,作为可执行文件(无论是脚本还是二进制文件),就像shell中的内置函数一样.
引用的常规内置表包含以下实用程序:
alias bg cd command false fc fg getopts jobs kill newgrp pwd read true umask unalias wait
注意:根据定义,特殊的内置实用程序仅限shell-internal,它们的行为与常规内置实用程序不同.
因此,要正式 POSIX兼容的操作系统确实必须提供cd
为外部工具.
同时,POSIX规范.确实意识到这些常规内置插件中的至少一些 - 特别是cd
- 仅作为内置有意义:
"由于cd
影响了当前的shell执行环境,因此它总是作为常规内置的shell提供. " - http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cd.html
在列出的常规内置实用程序中,有些作为内置实用程序和外部实用程序都有意义:
例如,kill
需要内置以杀死作业(这是一个shell 内部概念),但它也可用作外部实用程序,以便通过PID终止进程.
但是,在列出的常规内置实用程序中,以下内容永远不会像外部实用程序那样有意义,据我所知,如果您不同意 ,请告诉我,即使POSIX强制要求它们存在:
alias bg cd command fc fg getopts jobs read umask unalias
向Matt提供帮助完成清单的提示; 他还指出hash
内置的,即使它不是POSIX实用程序,也有一个毫无意义的脚本实现.
[1]正如Dave Newton在评论中指出的那样,可以以区分大小写的方式格式化HFS +(macOS文件系统)(即使大多数人坚持使用不区分大小写的默认值).根据Dave链接的答案,以下命令将告诉您macOS文件系统是否不区分大小写:
diskutil info / | grep -iq '^\s*Name.*case-sensitive*' && echo "case-SENSITIVE" || echo "case-INsensitive"
归档时间: |
|
查看次数: |
242 次 |
最近记录: |