如何创建别名并在 sh 中为所有用户使用(而不是在 bash 中)?

如何创建别名并在 sh 中为所有用户使用(而不是在 bash 中)?

我的问题可能很愚蠢,但我怎样才能让它alias适用sh于所有用户呢?

我知道我可以加一个别名,比如说这个:

alias ls='ls -l'

以便/etc/bash.bashrc能够工作,bash但是的等价物是什么sh

我尝试将其放入,/etc/profile但没有用。

答案1

将别名放入/etc/profileexec 后,执行以下命令:

源 /etc/profile

尝试此解决方案并在此处反馈。

答案2

总结

一般来说你不能。


维基百科对于 POSIX shell ( sh),启动/关闭脚本是

未指定(.profile作为示例)

我甚至没有找到这个例子POSIX.1-2017

实际上/etc/profile,它们~/.profile是源码(至少在 Linux 中,在sh我接触过的几个实现中是这样的)。就您的问题而言,问题在于它们仅由登录 shell 提供。并非每个 shell 都是登录 shell。并非每个交互式 shell 都是登录 shell。

此外鞋底登录 shell 的概念似乎没有被 POSIX 定义(如果我错了,请纠正我)。这个文件没有指定-l为的必需选项sh,尽管实际上许多实现使用它来强制登录 shell 行为。

即使/etc/profile由当前非登录 shell 的父进程解析,你也无法继承在那里定义的别名,因为别名无法导出;它们不会像导出变量那样在环境中传播。函数而不是别名也帮不了你

我的结论是:一般来说,你不能指望sh自动获取任何文件。要使每个sh源成为定义别名的特定文件,你需要找到(或编写)一个可以执行此操作的实现。

用户可以使用 手动获取文件. /path/to/file


但是,有一种方法可以让你ls像 一样工作ls -l。你可以用一个包装器脚本来做到这一点,该脚本将/bin/lsexec-s 替换为/bin/real_ls -l "$@"(其中real_ls是真正的ls重命名)。这种方法并不罕见,比较这个答案. 但也有缺点和陷阱。

  • 如果真实的ls是一个像这样的瑞士军刀二进制文件的符号链接busybox,那么当使用名称调用时,二进制文件会产生混淆real_ls

/another/dir/ls通过使用而不是 ,可以轻松避免这种情况real_ls。但即使如此

  • 将来的系统更新可能会覆盖您的自定义/bin/ls

现在可以通过将实际保留ls/bin/ls、将自定义ls放入/another/dir并将 添加到/another/dir作为PATH所有用户的第一个条目来避免这种情况(您通常可以通过 执行此操作/etc/profile)。但是然后

  • 每个使用ls和修改后的PATH变量(而不是/bin/ls完整路径)的脚本都会找到您的自定义ls

这很容易适得其反。如果你有一个别名,脚本(在子 shell 中运行,而不是源代码)就不会继承它。脚本可以为自己定义一个独立的别名,无论如何,ls脚本内部不依赖于任何“外部”别名;但它可能很容易依赖于可执行文件ls解析的任何内容。更改每个用户的行为ls可能会让他们有点不高兴,不过他们希望在交互式 shell 中调整。但更改ls每个现有脚本的行为是错误的,尤其ls是因为由 POSIX 定义并且定义明确指出其行为应取决于-l选项的存在。ls用自定义的lswherelsls -lare 等价替换将破坏其 POSIX 兼容性。

好吧,ls这不是最好的例子,因为无论如何都不应该解析其输出。另一方面,你永远不知道用户以何种方式(误用)任何工具。

另请注意,有可能有一个执行of shwherels是内置的。在这种情况下,使用/bin/lsor/and进行混淆PATH不能覆盖 plain 的ls含义;别名或函数可以。


如果你想有一个“全局”别名其他名称,例如

alias ll='ls -l'

那么切换到/bin/ll脚本对我来说看起来非常安全。ls保持完整,没有任何损坏。脚本可能如下所示:

#!/bin/sh
exec ls -l "$@"

相关内容