linux终端cd未找到命令,为什么`which`命令不能用于`cd`?我也找不到`cd`的可执行文件!...

问题描述

我尝试了which cd,它没有给出路径,而是返回退出代码1(用echo $?检查)。 coreutil cd本身正在工作,所以可执行文件应该在那里,对吧?我还为cd运行了find,但没有显示可执行文件。那怎么实现呢?

更新:

我不知道我是否应该在另一篇文章中提出这个问题,但由于我认为这里很好,我正在扩展(?)帖子……所以答案其实很简单,没有可执行文件 – 因为它是内置 – 但我发现一些内置(Fedora中的bash shell)有可执行文件!所以内置 – >我想,没有可执行文件是不对的?也许答案解释了内置实际上是什么(内置命令?),这实际上是这里的问题,而不是更多地关注cd …之前发布的一些好的链接表明内置不是程序……那么它们是什么?他们是如何工作的?它们只是shell的函数或线程吗?

最佳解决方案

命令cd不能是可执行文件

在shell中,cd用于“进入另一个目录”,或者更正式地用于更改curent工作目录(CWD)。作为外部命令实现它是不可能的:

该目录属于进程

curent工作目录是用于解释相对路径以获取可用于访问文件的完整路径的目录。相对路径在许多地方使用,一个过程中的解释不应影响另一个过程。因此,每个进程都有自己当前的工作目录。

cd是关于更改shell进程的当前工作目录,例如bash。

如果它是一个外部命令,路径中的可执行文件,运行该可执行文件将创建一个具有自己的工作目录的进程,而不会影响当前shell的进程。即使外部命令会改变它的目录,当外部进程退出时,该更改也会消失。

Shell内置命令

因此,为cd的任务运行外部命令是没有意义的。命令cd需要对当前运行的shell进程应用更改。

为此,它是shell的“builtin command”。

内置命令是与外部命令类似的命令,但是在shell中实现(因此cd不是coreutils的一部分)。这允许命令改变shell本身的状态,在这种情况下调用chdir()参见(参见man 2 chdir);

关于which

现在,标题问题的答案很简单:可执行命令which无法告诉我们cd是内置命令,因为可执行命令对内置命令一无所知。

替代type -a

作为which的替代品,您可以使用type -a;它可以看到可执行命令和内置函数;另外,它会看到别名和函数 – 也在shell中实现:

$ type -a cd

cd is a shell builtin

$ type -a type

type is a shell builtin

$ type -a which

which is /usr/bin/which

which is /bin/which

次佳解决方案

cd是一个内置的POSIX-mandated shell:

If a simple command results in a command name and an optional list of arguments, the following actions shall be performed:

If the command name does not contain any slashes, the first successful step in the following sequence shall occur:

If the command name matches the name of a utility listed in the following table, that utility shall be invoked.

cd

Otherwise, the command shall be searched for using the PATH…

虽然这没有明确说明它必须是内置,但规范接着说,在cd的描述中:

Since cd affects the current shell execution environment, it is always provided as a shell regular built-in.

从bash手册:

The following shell builtin commands are inherited from the Bourne Shell. These commands are implemented as specified by the POSIX standard.

cd cd [-L|[-P [-e]]] [directory]

我想你可以想到一个架构,其中cd不一定是内置的。但是,你必须看看内置意味着什么。如果你在shell中编写特殊代码来为某个命令做一些事情,你就会接近内置。你做的越多,只需要内置就越好。

例如,你可以让shell有IPC与子进程通信,并且会有一个cd程序,它会检查目录是否存在以及你是否有权访问它,然后与shell通信以告诉它改变它的目录。但是,您必须检查与您通信的进程是否是子进程(或者只与子进程通信的特殊方式,例如特殊文件描述符,共享内存等),如果进程实际上是运行受信任的cd程序或其他东西。这是一整套蠕虫。

或者您可以使用cd程序进行chdir系统调用,并启动一个新shell,其中所有当前环境变量都应用于新shell,然后在完成时以某种方式终止其父shell。

更糟糕的是,您甚至可以拥有一个系统,其中一个进程可以改变其他进程的环境(我认为从技术上讲,您可以使用调试器来完成此操作)。然而,这样的系统将非常非常脆弱。

您将发现自己添加了越来越多的代码来保护这些方法,而简单地将其作为内置函数则相当简单。

某些东西是可执行文件并不能阻止它成为内置函数。例证:

echo和test

echo和test是POSIX-mandated用途(/bin/echo和/bin/test)。然而,几乎所有流行的 shell 都有内置的echo和test。同样,kill也是内置的,可作为程序使用。其他包括:

sleep(不常见)

time

false

true

printf

但是,在某些情况下,命令不能是内置命令。其中之一是cd。通常,如果未指定完整路径,并且命令名称与内置命令名称匹配,则调用适合该命令的函数。取决于shell,内置的行为和可执行文件的行为可能不同(对于具有wildly differing behaviours的echo,这尤其是个问题。如果您想确定行为,最好使用完整的调用可执行文件路径,并设置像POSIXLY_CORRECT的变量(即使那时没有真正的保证)。

从技术上讲,没有什么可以阻止你提供一个也是一个shell的操作系统,并且每个命令都是内置的。接近这个极端的是单片BusyBox。 BusyBox是一个单独的二进制文件(取决于它所调用的名称)可以表现为任何over 240 programs,包括Almquist Shell(ash)。如果在运行BusyBox ash时取消设置PATH,则仍可访问BusyBox中可用的程序,而无需指定PATH。它们接近于shell内置,除了shell本身是内置于BusyBox的sort-of。

案例研究:Debian Almquist Shell(dash)

如果查看dash源代码,执行线程就是这样的(当然,在使用管道和其他东西时还会涉及其他功能):

main→cmdloop→evaltree→evalcommand

然后,evalcommand使用findcommand来确定命令是什么。如果它是内置的,then:

case CMDBUILTIN:

if (spclbltin > 0 || argc == 0) {

poplocalvars(1);

if (execcmd && argc > 1)

listsetvar(varlist.list, VEXPORT);

}

if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {

if (exception == EXERROR && spclbltin <= 0) {

FORCEINTON;

break;

cmdentry.u.cmd是struct(struct builtincmd),其成员之一是功能指针,具有典型的main:(int, char **)的特征。 evalbltin函数调用(取决于内置函数是否为eval命令)evalcmd或此函数指针。实际功能在各种源文件中定义。例如,echo是:

int

echocmd(int argc, char **argv)

{

int nonl;

nonl = *++argv ? equal(*argv, "-n") : 0;

argv += nonl;

do {

int c;

if (likely(*argv))

nonl += print_escape_str("%s", NULL, NULL, *argv++);

if (nonl > 0)

break;

c = *argv ? ' ' : '\n';

out1c(c);

} while (*argv);

return 0;

}

本节中源代码的所有链接均为行number-based,因此它们可能会更改,恕不另行通知。

1 POSIX系统具有cd可执行文件。

边注:

在Unix和Linux上有很多优秀的帖子。处理shell行为的Linux。特别是:

If you haven’t noticed a pattern in the questions listed so far, nearly all of them involve Stéphane Chazelas.

第三种解决方案

您找不到cd的可执行文件,因为没有。

cd是shell的内部命令(例如bash)。

第四种方案

来自man which:

which returns the pathnames of the files (or links) which would be executed in the current environment, had its arguments been given as commands in a strictly POSIX-conformant shell. It does this by searching the PATH for executable files matching the names of the arguments. It does not follow symbolic links.

从which的描述可以看出,它只是检查PATH。因此,如果您实施了一些bash function,它将不会显示任何内容。最好使用type命令和which。

例如,在Ubuntu ls命令中别名为ls --color=auto。

$ type ls

ls is aliased to `ls --color=auto'

$ which ls

/bin/ls

如果您实现测试功能hello:

$ function hello() { for i in {1,2,3}; do echo Hello $i;done }

$ which hello

which什么都没有显示。但是type:

$ type hello

hello is a function

hello ()

{

for i in {1,2,3};

do

echo Hello $i;

done

}

在你的情况下:

$ type cd

cd is a shell builtin

这意味着cd是shell builtin,它位于bash内。所有bash builtins在man bash中描述,在SHELL BUILTIN命令中

SHELL BUILTIN COMMANDS

Unless otherwise noted, each builtin command documented in this section

as accepting options preceded by - accepts -- to signify the end of the

options. The :, true, false, and test builtins do not accept options

and do not treat -- specially. The exit, logout, break, continue, let,

and shift builtins accept and process arguments beginning with - with‐

out requiring --. Other builtins that accept arguments but are not

specified as accepting options interpret arguments beginning with - as

invalid options and require -- to prevent this interpretation.

参考资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xenix — 微软与UNIX的短暂爱恋

微软向外宣布Microsoft Xenix OS&#xff0c;一个为16位微处理器开发的可移植的操作系统。它是一个交互的&#xff0c;多用户多任务系统&#xff0c;可以运行在Intel 8086, Zilog Z8000, Motorola M68000以及DEC公司的PDP-11系统计算机上。所有微软已经开发的系统软件&#xff…

optionals_Java Optionals获得更具表现力的代码

optionals我们中任何使用允许空引用的语言进行编程的人&#xff0c;都将在尝试取消引用一个引用时经历过。 无论是导致segfault还是NullPointerException&#xff0c;它始终是一个错误。 托尼霍尔将其描述为他十亿美元的错误 。 当函数向客户端的开发人员未预料到的客户端返回空…

python排序sorted_sorted排序的两个方法 - Python

在给列表排序时&#xff0c;sorted非常好用&#xff0c;语法如下&#xff1a; sorted(iterable[, cmp[,key[,reverse]]]) 简单列表排序&#xff0c;很容易完成&#xff0c;sorted(list)返回的对象就是列表结果&#xff0c;但是遇到列表中嵌套元组时&#xff0c;需要使用特殊的方…

linux vim自动执行快捷键,Linux Vim快捷键操作命令整理

VIM中常用的替换模式总结1&#xff0c;简单替换表达式替换命令可以在全文中用一个单词替换另一个单词&#xff1a;:%s/four/4/g“%” 范围前缀表示在所有行中执行替换。最后的 “g” 标记表示替换行中的所有匹配点。如果仅仅对当前行进行操作&#xff0c;那么只要去掉%即可如果…

Mach 微内核的命名趣闻

据 Tevanian 说&#xff0c;MACH&#xff0c;源于一个读音错误。当时他正和其他人在匹兹堡一个下雨天里一边躲避着路上的泥水坑&#xff0c;一边讨论着新内核的事&#xff0c;Tevanian开玩笑地建议他们的新微核命名为MUCK&#xff0c;意为“多用户通信内核”&#xff08;Multi-…

eclipse占用内存过大_Java性能调优学习(三)-jmap+mat分析内存溢出问题实战

上一节我们讲了jinfo&#xff0c;jstat&#xff0c;jmap的使用&#xff0c;还简单的讲了下如何使用jmap导出内存映像文件&#xff0c;这次&#xff0c;我们来实战一把内存溢出问题。环境准备首先我们先模拟一下内存溢出的场景&#xff0c;以下这段代码在访问后肯定会造成堆内存…

spring boot自测_将测微仪与Spring Boot 2一起使用

spring boot自测这是快速入门&#xff0c;介绍了如何使用出色的Micrometer库来检测基于Spring Boot 2的应用程序并在Prometheus中记录指标 介绍 Micrometer在不同监视工具提供的客户端库上提供了基于Java的外观。 以Prometheus为例&#xff0c;如果我要将Java应用程序与Prome…

arch linux界面优化,Archlinux 启动优化

内核参数优化修改/boot/grub/grub.cfg 添加libahci.ignore_sss1 #禁用sssraidnoautodetectipv6.disable1 #禁用ipv6nomodeset #不使用kms&#xff0c;plymouth.enable0 #禁用plymouthrootfstypeext4 #root分区类型selinux0#禁用selinux 完成后&#xff1a;linux /vmlinuz-lin…

微软和 Windows 的发展简史

20世纪60年代中期&#xff0c;美国达特茅斯学院院长、匈牙利人约翰凯梅尼&#xff08;J. Kemeny&#xff09;和数学系教授托马斯卡茨&#xff08;Thomas E. Kurtz&#xff09;认为&#xff0c;像FORTRAN&#xff08;世界上最早出现的计算机高级程序设计语言&#xff09;那样的语…

elaseticsearch 配置ik分词器的热更新_Elasticsearch从入门到放弃:分词器初印象

Elasticsearch 系列回来了&#xff0c;先给因为这个系列关注我的同学说声抱歉&#xff0c;拖了这么久才回来&#xff0c;这个系列虽然叫「Elasticsearch 从入门到放弃」&#xff0c;但只有三篇就放弃还是有点过分的&#xff0c;所以还是回来继续更新。之前我们聊过了 Elasticse…

java api限流_Java 9:流API的增强

java api限流Java 9向Stream接口添加了4种新方法&#xff1a; 1. dropWhile dropWhile方法类似于skip方法&#xff0c;但使用Predicate而不是固定的整数值。 当Predicate为true时&#xff0c;它将从输入流中删除元素。 然后将所有剩余的元素传递到输出流。 例如&#xff1a; …

服务器windows模拟linux环境,科学网—Windows不用虚拟机或双系统,轻松实现shell环境:gitforwindows - 刘永鑫的博文...

windows缺少shell命令支持用过Linux服务器分析数据的小伙伴&#xff0c;一定对Linux强大Shell命令所折服&#xff0c;经常会感觉windows缺少这些命令而感觉不方便。还有想学习Linux Shell命令的小伙伴&#xff0c;一直没有一个很好的学习环境。双系统安装涉及分区改变对硬盘数据…

Mac OS 系统的发展历史

文章目录System 1.0&#xff08;1984&#xff09;System 2.0&#xff08;1985&#xff09;System 3.0&#xff08;1986&#xff09;System 4.0&#xff08;1987&#xff09;System 5.0&#xff08;1987&#xff09;System 6.0 &#xff08;1988&#xff09;System 7 (1991 )Sys…

pythonselenium兼容性_对于旧版Google Chrome,无法在Python中使用Selenium找到Chrome

出于兼容性原因&#xff0c;我更喜欢将Chrome版本55.0.2883.75与Chromedriver v.2.26一起使用。我从https://www.slimjet.com/chrome/google-chrome-old-version.php和Chromedriver 2.26从https://chromedriver.storage.googleapis.com/index.html?path下载了较旧版本的chrome…

弱投影模型_通过投影增强数据模型

弱投影模型介绍 数据模型可能很棘手。 建模可能会更加困难。 有时候&#xff0c;应该放入数据库表中的信息不一定是我们要在每段代码中使用的信息。 和其他许多次一样&#xff0c;Spring来了。 一个称为投影的小功能可以帮助我们在普通界面中仅用几行数据映射数据。 在本文中…

苹果公司的电脑发展史——硬件篇

文章目录一、Apple I&#xff08;1976&#xff09;二、Apple II&#xff08;1977&#xff09;三、Lisa&#xff08;1983&#xff09;四、Macintosh&#xff08;1984&#xff09;五、PowerBook&#xff08;1991&#xff09;六、iMac&#xff08;1998&#xff09;七、iBook&#…

linux attach 指令,以太坊实战-attach命令详解

在前面的实战教程中我们经常提到attach这个命令&#xff0c;今天就针对此命令做更深一步的介绍。官方对此参数的解释如下&#xff1a;attach Start an interactive JavaScript environment (connect to node)也就是说它是一个连接到节点的JavaScript环境的交互窗口。通过它我们…

my.ini修改后服务无法启动_Spring Cloud Eureka 服务实现不停机(Zero-downtime)部署

问题互联网产品高速迭代&#xff0c;通常伴随着高频次的版本发布。部署新版上线需要重启服务&#xff0c;直接 kill 服务进程可能会造成服务短暂不可用&#xff0c;从而影响到正在使用的用户。Spring Cloud 项目中一般会用到 Ribbon 作为负载均衡&#xff0c;那么是不是只要保证…

苹果电脑 Mac OS X 系统诞生的故事和发展历史

文章目录CoplandNeXTRhapsodyOS XPublic Beta (Kodiak)Mac OS X v10.0 (Cheetah)Mac OS X v10.1 (Puma)Mac OS X v10.2 (Jaguar)Mac OS X v10.3 (Panther)Mac OS X v10.4 (Tiger)Mac OS X v10.5 (Leopard)Mac OS X v10.6 (Snow Leopard)Mac OS X Lion2001 年 3 月 24 日&#x…

linux系统普通用户ssh不能登陆,关于CentOS普通用户无法登录SSH问题

Linux命令的返回码列表转自:http://blog.chinaunix.net/uid-10347480-id-3263127.html 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序 ...iOS开发 GET、POST请求方法(NSURLConnection篇)Web Service使用的主要协议是HTTP协议,即超文本传输协议.…