在源脚本中禁用函数/别名 [英] Disable functions/aliases in a sourced script
问题描述
我知道我可以运行原创"命令(不是别名)使用 \
或 ""
:
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中实现,不能更改.help
和enable
列出所有内置函数. $PATH
中的可执行文件
- aliases
can be defined by the user usingalias cmd=...
- functions
can be defined by the user usingcmd() { ... }
- built-ins
are directly implement in bash and cannot be altered.help
andenable
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 允许您使用引用和内置 command
和 builtin
来影响选择哪种类型.
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 -f
和 unalias
,并在最后恢复它们.但是,对于只读函数,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
.
请注意:获取您脚本的调用者甚至可能禁用或隐藏command
、builtin
等——因此您可以永远不要确定您实际上正在使用您期望的命令.即使编写 /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屋!