【问题标题】:Is there an alternative for .bashrc for /bin/sh?/bin/sh 的 .bashrc 是否有替代方案?
【发布时间】:2017-01-30 00:26:36
【问题描述】:

我需要一个在/bin/sh 启动时运行的脚本,类似于.bashrc/bin/bash。有没有办法做到这一点?

编辑:

我尝试了/etc/profile~/.profile,我在这两个文件中都写了echo 'hello world'。这些都不起作用。当我在控制台中输入sh 时,什么都没有弹出。

我正在使用 ArchLinux。

【问题讨论】:

  • 你可以使用~/.profile
  • 谢谢,但它不起作用
  • Arch Linux 不提供 Bourne shell(这是 1970 年代的规范)。也许您正在考虑 POSIX sh(可以追溯到 90 年代)?
  • 您可以很容易地分辨出您使用的是哪一个:在 Bourne 中,^ 支持管道字符,而对于 POSIX 兼容的 /bin/sh,它仅支持 |。那么,echo hello ^ cat 是在其输出上发出字符串 hello ^ cat(表示您在 POSIX sh 上),还是发出 hello(表示您在 Bourne)?
  • @CharlesDuffy 是的,你是对的,它是 POSIX sh。

标签: linux shell sh


【解决方案1】:

在 Arch 中,/bin/sh 是到 /bin/bash 的符号链接,它有很多关于启动脚本的规则,在调用 sh 时有特殊情况:

如果使用名称 sh 调用 bash,它会尝试模仿启动 尽可能接近 sh 的历史版本的行为,...

如果您从控制台启动它,而不使用任何命令,即作为交互式、非登录 shell,您应该使用 ENV 变量:

export ENV=~/.profile
sh

ENV=~/.profile sh 

当作为一个名为 sh 的 交互式 [非登录] shell 调用时,bash 会查找变量 ENV,如果已定义则扩展其值,并将扩展后的值用作要读取和执行的文件。

或者,您可以使用--login 选项使其表现得像一个登录shell,并读取.profile 文件。

sh --login

作为交互式登录 shell [使用名称 sh] 调用时,或者 带有 --login 选项的非交互式 shell,它首先尝试 从 /etc/profile 和 ~/.profile 读取并执行命令 顺序

【讨论】:

  • 我用过这个。我所要做的就是添加--login 选项。尽管我很确定这种方法在我的情况下在哲学上是不正确的,但它是有效的,我不在乎。谢谢。
【解决方案2】:

我假设你的/bin/shdash

对于 dash,将环境变量 ENV 设置为您选择的初始化文件的路径。这将是 dash 对 ~/.bashrc 的模拟。

如果您对登录 shell 感兴趣,dash 改为 ~/.profile

例如,可以添加到~/.profile

ENV=$HOME/.shinit; export ENV

这将导致dash 在交互式 shell 启动时读取 ~/.shinit

编辑

“我尝试了 /etc/profile 和 ~/.profile,我写了 echo 'hello world' 到这两个文件。这些都不起作用。当我输入 sh 到 控制台,什么都没有弹出。”

这些文件login shell 读取。如果你只是在命令提示符下运行sh,你正在启动一个交互式 shell。

文档

来自man dash

调用
如果不存在 args 并且如果 shell 连接到终端(或者如果设置了 -i 标志),并且 -c 选项不存在,shell 被认为是交互式的 贝壳。交互式 shell 通常会在每个命令之前进行提示,并且 处理编程和命令错误 不同(如下所述)。首次启动时,shell 检查参数 0,如果它以破折号“-”开头,则 shell 是 也被认为是 登录外壳。这通常在用户首次登录时由系统自动完成。登录 shell 首先从 文件 /etc/profile 和 .profile (如果存在)。如果 环境变量 ENV 在进入交互式 shell 时设置,或者 在登录外壳的 .profile 中设置,外壳接下来读取 来自以 ENV 命名的文件的命令。 因此,用户应该放置 仅在登录时在 .profile 中执行的命令 文件,以及为每个交互式 shell 执行的命令 在 ENV 文件中。 要将 ENV 变量设置为某个文件,请将 主目录的 .profile 中的以下行

       ENV=$HOME/.shinit; export ENV

用你想要的任何文件名替换“.shinit”。

如果指定了选项以外的命令行参数, 然后 shell 将第一个参数视为文件的名称 读取命令(shell 脚本)和剩余参数 设置为 shell 的位置参数($1、$2 等)。 否则,shell 从其标准输入读取命令。 [强调添加。]

POSIX

来自POSIX standard(帽子提示:chepner):

ENV
这个变量,当且仅当交互式 shell 是 调用,应进行参数扩展(见参数 扩展)由外壳,结果值应用作 包含要在当前执行的 shell 命令的文件的路径名 环境。该文件不必是可执行的。如果扩展值 ENV 不是绝对路径名,结果未指定。环境噪声 如果真实有效的用户 ID 或真实有效的用户 ID 应被忽略 进程的有效组ID不同。

【讨论】:

  • 请注意,ENV 是 POSIX 标准的一部分,而不是特定于 dash。 (dash 甚至 对标准的任何扩展吗?)
  • 如果 .profile 不被解释为交互式 shell,ENV 技巧会起作用吗?
  • @karlosss,这就是export ENV 的意义所在:它是通过作为子进程运行的交互式shell 从您的登录shell 继承而来的。请注意,如果您要从您的 ENV 脚本中访问 echo,您应该首先检查当前的 shell 是否是交互式的——您将通过让您的 dotfiles 发出内容来破坏一堆程序(如 rsync)在非交互式 shell 上的标准输出上。
  • 对不起,也许这是一个相当新手的问题,但是如何获得这项工作?当我输入sh 时,什么都没有弹出。我的~/.profile 文件中有“ENV 技巧”。 shell 是交互式的,$- 变量包含i
  • @karlosss,好吧,您是否真的注销并重新登录,以便运行您的.profile?或者echo "$ENV" 反映预期值?如果您的 .profile 没有在登录时运行,那么值得查看您的登录 shell,例如,如果它是 bash 并找到 .bash_profile.bash_login,则您的 .profile 可能不会被执行,除非您获取它来自其他两个[如果它们存在]。
猜你喜欢
  • 2022-08-19
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2020-10-07
  • 2012-09-02
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多