如何为所有用户制作别名并为sh工作(不是在bash中)?


0

我的问题也许是愚蠢的,但我怎样才能使一个alias以工作中的sh所有用户?

我知道我可以加一个别名,让我说一句:

alias ls='ls -l'

/etc/bash.bashrc工作bash但是相当于什么sh

我试图放入/etc/profile但不起作用。


不能是sh唯一的一个符号链接到您的首选的壳呢?
Bobby 2013年

which sh:/ bin / sh
Thanasis Petsas 2013年

对我来说which sh仍然说sh虽然它是bash的符号链接。realpath sh然而,另有说明。
miyalys

Answers:



0

TL;博士

一般来说,你不能。


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

未指定(.profile以示例为例)

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

在实践中/etc/profile并且~/.profile来源(至少在Linux中,sh我使用的实现很少)。在您的问题的上下文中,问题是它们仅由登录shell提供。并非每个sh​​ell都是登录shell。并非每个交互式shell都是登录shell。

此外,登录shell的唯一概念似乎不是由POSIX定义的(如果我错了,有人会纠正我)。虽然在实践中许多实现使用它来强制登录shell行为,但是本文档未指定-l为必需选项sh

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

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

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


然而,有一种方法可以让你ls像工作一样ls -l。您可以通过替换/bin/lsexec-s到的包装脚本来执行此操作/bin/real_ls -l "$@"(其中real_lsls重命名的实际位置)。这种方法并不罕见,比较这个答案。但是存在缺点和陷阱。

  • 如果真实ls是瑞士军刀二进制文件的符号链接busybox,那么二进制文件如果被名称调用则会混淆real_ls

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

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

现在,这可以通过留下真正避免ls/bin/ls,将您的自定义ls/another/dir,并加入/another/dirPATH为所有用户的第一个条目(这个你可以通过平时做/etc/profile)。但是之后

  • 每个使用的脚本ls和修改后的PATH变量(相对于/bin/ls完整路径)都将找到您的自定义ls

这可能很容易适得其反。如果你有一个别名,脚本(在子shell中运行,不是源代码)将不会继承它。脚本可以为自己定义一个独立的别名,无论如何ls,脚本内部不依赖于任何“外部”别名; 但它可能很容易依赖于任何可执行程序ls解析。改变ls每个用户的行为可能会让他们感到不安,但他们希望能够在他们的交互式shell中进行调整。但是改变ls每个现有脚本的行为是错误的,特别是因为它ls由POSIX定义的,并且定义明确指出它的行为应该取决于-l选项的存在。更换ls与您的自定义ls,其中lsls -l 相当于将打破其POSIX合规性。

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

还要注意它可能有一个执行sh地方ls是内置。在这种情况下,使用/bin/ls或/和PATH不能覆盖普通ls手段; 别名或功能可以。


如果您想要一个具有其他名称的“全局”别名,例如

alias ll='ls -l'

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

#!/bin/sh
exec ls -l "$@"
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.