禁用源脚本中的函数/别名

NPS*_*NPS 3 bash alias function

\我知道我可以使用或运行“原始”命令(不是别名)""

\ls
"ls"
Run Code Online (Sandbox Code Playgroud)

但这不适用于函数。它还要求我每次都使用该语法。

是否可以在源脚本中禁用父进程(运行我的脚本的进程)中的所有函数/别名?即,如果终端中的用户定义了一些别名函数,我希望它们在我的脚本中禁用(但当然我仍然希望能够定义和使用我自己的别名/函数)。

Soc*_*owi 8

Bash 中的命令类型

\n

Bash 知道不同类型的命令可以相互影响。这些类型的优先级是:

\n
    \n
  • 别名
    \n可以由用户定义alias cmd=...
  • \n
  • 函数
    \n可以由用户定义cmd() { ... }
  • \n
  • 内置
    \n直接在 bash 中实现,不能更改。helpenable列出所有内置函数。
  • \n
  • 可执行文件位于$PATH
  • \n
\n

意思是,如果您键入,cmd arg1 arg2 ...则使用别名cmd(如果已定义),否则使用该函数cmd(如果已定义),否则使用内置函数(cmd如果它是内置的),否则使用cmd目录中的第一个可执行文件$PATH(如果有)一,否则你会得到错误-bash: cmd command not found

\n

cmd可以使用 检查哪些情况适用type -a cmd

\n

手动优先控制

\n

Bash 允许您使用引用以及内置的command和来影响选择哪种类型builtin

\n
    \n
  • \\cmd
    \ns抑制别名
    \n使用函数、内置函数、可执行文件
  • \n
  • command cmd
    \ns抑制别名和函数
    \n使用内置函数和可执行文件
  • \n
  • builtin cmd
    \n抑制别名、函数和可执行文件
    \n仅使用内置函数
  • \n
  • enable -n cmd
    \n完全禁用内置功能cmd,以便之后仅
    使用\n别名、函数和可执行文件
  • \n
  • env cmd
    \n不是内置的 bash,因此它不会真正抑制任何内容,
    \n仅使用可执行文件
  • \n
\n

例子

\n

阴影是完全正常的。例如,bash 有它自己的内置的echo,但您的系统也有/bin/echo. 两种实现可能有所不同。例如,我的echobash 5 支持\\uXXXX,但我的echoGNU coreutils 8.3 不支持。如果您使用别名和函数添加自己的实现,这种差异的可能性会变得更加明显。这是交互式 bash 会话中的一个示例($ 是提示符):

\n
$ echo() { printf "function echo: %s\\n" "$*"; }\n$ alias echo=\'printf "alias echo: %s %s %s\\n"\'\n$ type -a echo\necho is aliased to `printf "alias echo: %s %s %s\\n"\'\necho is a function\necho ()\n{\n    printf "function echo: %s\\n" "$*"\n}\necho is a shell builtin\necho is /bin/echo\n\n$ echo -e \'\\u2261\'\nalias echo: -e \\u2261\n$ \\echo -e \'\\u2261\'\nfunction echo: -e \\u2261\n# use the built-in (or executable file if there was no such built-in)\n$ command echo -e \'\\u2261\'\n\xe2\x89\xa1\n$ builtin echo -e \'\\u2261\'\n\xe2\x89\xa1\n\n# use the executable /bin/echo\n$ env echo -e \'\\u2261\'\n\\u2261\n\n$ enable -n echo\n# use the executable /bin/echo (`command` is needed to skip the alias and function)\n$ command echo -e \'\\u2261\'\n\\u2261\n
Run Code Online (Sandbox Code Playgroud)\n

回答你的问题

\n

不幸的是,我不知道诸如enable永久禁用别名和函数查找之类的事情。您可以尝试一些技巧,例如备份所有别名和函数,对它们进行操作unset -funalias最后恢复它们。但是,unset只读函数可能会失败。更好的方法是用于bash -c \'... functions and aliases have no effect here ...\'那些您并不真正需要source. 对于其他部分,请为所有内容添加前缀command

\n

请注意:获取您的脚本的调用者甚至可能禁用或隐藏commandbuiltin等 - 因此您永远无法确定您实际上正在使用您期望的命令。即使写入/usr/bin/env executable/path/to/the/executable作为函数没有帮助,也可以更改名称和/$PATH或文件系统。\n但是,这不应该是您关心的问题。提供脚本的人应该负责提供正确的环境。

\n

  • 一个很好的答案!然而,一个挑剔的是,[POSIX `env` 文档](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html) 说,如果 `env` 的参数是内置的中,结果未定义。因此,说“env”“仅使用可执行文件”可能是不正确的。 (2认同)