Shell函数在Linux上存储在哪里?


11

刚开始时,我在寻找which某些程序作为参数后不输出任何内容的原因,例如cd

根据我在这里找到的信息,原因可能是cd我的机器上有一个功能,可以通过运行确认type cd

TLDR:但是,由于which可以将由于$PATH变量而可以定位的普通程序放在这些$PATH文件夹之一中,因此函数或脚本之类的cd存储在哪里?

user@linuxmchine:~$ type cd
cd is a function
cd () 
{ 
    __zsh_like_cd cd "$@"
}

我懂了cd is a shell builtin。看看您的shell(zsh?)的手册页
Xen2050

1
请查看unix.stackexchange.com/questions/85249/…问题在于,这是一个不应该使用的旧命令-尤其是因为诸如此类的问题。

Answers:


12

用户定义的功能

通常,bash函数永久存储在bash启动脚本中。

  • 系统范围内的启动脚本:/etc/profile用于登录Shell和/etc/bashrc交互式Shell。
  • 用户定义启动脚本:~/.bash_profile用于登录Shell和~/.bashrc交互式Shell。
  • 有关交互式/登录shell的更多信息man,请参见INVOCATION部分的bash 页面。

当bash启动时,用户定义的shell函数会动态加载到哈希(或查找表)中。在bash源文件variable.c中,表的定义为:

/* The list of shell functions that the user has created, or that came from
   the environment. */
HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;

用户定义的函数可以使用bash declare命令列出,其他shell仍在使用typeset。在bash中declare已取代typeset命令。

declare -f

这些函数在bash shell的生存期内存在于内存中。

Shell定义(内置)函数

这些都是常见的功能,例如echoprintfcd:。它们被编译成链接到bash可执行文件的库。与加载外部定义相比,将定义构建到可执行文件中可以节省时间。这些功能的定义(保存在.def解析为C源代码的源文件中)保存在builtinsbash源代码的目录中。

除了有用的信息:有关shell内置命令的信息,请使用help <command>。例如

help                # list all builtins
help declare        # info and options for declare
help -m declare     # gives man style information for declare

谢谢您的摘录答案。这正是我一直在寻找的东西。您是否认为有一种工具可以遵循bash函数的创建过程,或者类似的东西typeset可以显示是什么文件/脚本导致了函数的创建/更改?
GabrijelŠimunović2014年

我不知道任何这样的工具-这对于declareor typeset命令来说是一个有用的选项,用于显示函数定义的源文件。我认为这是软件工程问题。最近发现在.alias文件中定义的Shell函数-不是我所期望的!
嫌疑犯2014年

8

Shell 函数存储在Shell 的内存中(或者可能存储在未记录的临时文件中)。他们不以任何方式使用存在,直到外壳程序启动(例如,当您登录到CLI或启动一个shell窗口等xterm)和它们被定义(例如,通过阅读.bashrc.bash_profile或类似的东西),他们不再外壳终止时存在。


1
您在提示符下键入的内容的短暂性质很重要。我的投票投给了这个答案。如果cd () { pwd; builtin cd "$@"; }在提示符下键入,则存储的唯一位置是当前运行的Shell的内存中。(我的示例是Bash,但同一原理适用于任何shell。)
Tripleee 2014年

6

cd和其它公共命令喜欢echotypealias是所谓的内建

内置命令包含在外壳程序本身内,并且不同的外壳程序可能具有不同的内置命令。


4
我不知道是否值得强调将诸如内置命令之类的可执行代码cd包含在外壳程序本身中,例如,/bin/bash如果是您的外壳,则包含在文件中。(我确实认为您的措辞很清楚,但我已经看到人们对各种各样的事情感到困惑。)
David Z

1

超级用户问题查找bash函数的定义 与此密切相关。用户HairOfTheDog提供了以下答案(解释如下):

以下命令将报告函数定义的位置(文件名和行号)。假设一个名为的函数foo

# Turn on extended shell debugging
shopt -s extdebug

# Display the function’s name, line number and fully qualified source file
declare -F foo

# Turn off extended shell debugging
shopt -u extdebug

例如,这些命令的输出可能是:

foo 32 /source/private/main/developer/cue.pub.sh

上面的内容可能仅在中有效bash,而在POSIX shell中通常无效。

感谢Blue Raspberry找到这个!

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.