在源脚本中禁用函数/别名 [英] Disable functions/aliases in a sourced script

查看:19
本文介绍了在源脚本中禁用函数/别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以运行原创"命令(不是别名)使用 \"":

I know I can run an "original" command (not alias) using either \ or "":

\ls
"ls"

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

This doesn't work for functions though. Also it requires me to use that syntax every time.

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

Is it possible in a sourced script to disable all functions/aliases from the parent process (one which runs my script)? I.e. if a user in their terminal has some aliases functions defined I want them disabled in my script (but of course I still want to be able to define and use aliases/functions of my own).

推荐答案

Bash 中的命令类型

Bash 知道可以相互遮蔽的不同类型的命令.这些类型的优先级是:

Types of Commands in Bash

Bash knows different types of commands which can shadow each other. The precedence of these types is:

  • 别名
    可以由用户使用alias cmd=...
  • 定义
  • 功能
    可以由用户使用 cmd() { ... }
  • 定义
  • 内置插件
    直接在bash中实现,不能更改.helpenable 列出所有内置函数.
  • $PATH
  • 中的可执行文件
  • aliases
    can be defined by the user using alias cmd=...
  • functions
    can be defined by the user using cmd() { ... }
  • built-ins
    are directly implement in bash and cannot be altered. help and enable list all built-ins.
  • Executable files in $PATH

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

Meaning if you type cmd arg1 arg2 ... you use the alias cmd if it is defined, otherwise you use the function cmd if it is defined, otherwise you use the built-in cmd if it is built-in, otherwise you use the first executable cmd from the directories in $PATH if there is one, otherwise you end up with the error -bash: cmd command not found.

可以使用type -a cmd检查这些情况中哪些适用于cmd.

Which of these cases applies for cmd can be checked using type -a cmd.

Bash 允许您使用引用和内置 commandbuiltin 来影响选择哪种类型.

Bash allows you to influence which type to pick using quoting and the built-ins command and builtin.

  • \cmd
    禁止别名
    使用函数、内置函数、可执行文件
  • command cmd
    禁止别名和函数
    使用内置程序和可执行文件
  • 内置cmd
    禁止别名、函数和可执行文件
    仅使用内置函数
  • 启用 -n cmd
    完全禁用内置的cmd,这样之后只有
    使用别名、函数和可执行文件
  • env cmd
    不是内置的 bash,因此它并没有真正抑制任何东西,但是
    仅使用可执行文件

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

Shadowing is perfectly normal. For instance, bash has its own built-in echo, but your system also has /bin/echo. Both implementations may differ. For instance, my echo from bash 5 supports \uXXXX but my echo from GNU coreutils 8.3 does not. The possibility of such differences becomes even more clear if you add your own implementations using aliases and functions. Here's an example in an interactive bash session ($ is the prompt):

$ echo() { printf "function echo: %s\n" "$*"; }
$ alias echo='printf "alias echo: %s %s %s\n"'
$ type -a echo
echo is aliased to `printf "alias echo: %s %s %s\n"'
echo is a function
echo ()
{
    printf "function echo: %s\n" "$*"
}
echo is a shell builtin
echo is /bin/echo

$ echo -e '\u2261'
alias echo: -e \u2261
$ \echo -e '\u2261'
function echo: -e \u2261
# use the built-in (or executable file if there was no such built-in)
$ command echo -e '\u2261'
≡
$ builtin echo -e '\u2261'
≡

# use the executable /bin/echo
$ env echo -e '\u2261'
\u2261

$ enable -n echo
# use the executable /bin/echo (`command` is needed to skip the alias and function)
$ command echo -e '\u2261'
\u2261

回答您的问题

不幸的是,我不知道像 enable 这样的东西可以永久禁用别名和函数查找.您可以尝试一些技巧,例如备份所有别名和函数,对它们执行 unset -funalias,并在最后恢复它们.但是,对于只读函数,unset 可能会失败.更好的方法是使用 bash -c '... 函数和别名在这里没有影响...' 对于您并不真正需要 source<的好处的部分/代码>.对于其他部分,以 command 为前缀.

Answering your Question

Unfortunately I'm not aware of something like enable to permanently disable alias and function lookup. You could try some hacks like backing up all aliases and functions, doing unset -f and unalias on them, and restoring them at the end. However, unset may fail for readonly functions. The better way would be to use bash -c '... functions and aliases have no effect here ...' for the parts where you don't really need the benefits of source. For the other parts, prefix everything with command.

请注意:获取您脚本的调用者甚至可能禁用或隐藏commandbuiltin 等——因此您可以永远不要确定您实际上正在使用您期望的命令.即使编写 /usr/bin/env executable/path/to/the/executable 也无济于事,因为函数可以具有名称和 $PATH 或文件系统可以被改变.但是,这不应该是您的问题.提供脚本的人应该负责提供正确的环境.

Please note: The caller who sources your script may even disable or shadow command, builtin, and so on -- therefore you can never be sure that you are actually using the commands you expected. Even writing /usr/bin/env executable or /path/to/the/executable does not help as a function can have the name and $PATH or the file system can be altered. However, that shouldn't be your concern. The one who sources your script should be responsible for providing the correct environment.

这篇关于在源脚本中禁用函数/别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆