在我的 Ubuntu 12.04 上,登录是由为用户lightdm
启动一个实例来处理的,该实例然后启动用户单击的应用程序。在此路径中的某个位置,文件被获取,但无论是谁获取它,都使用 来执行此操作,无论用户的登录 shell 状态如何。gnome-session
compiz
.profile
/bin/sh
/etc/passwd
这对我来说是有问题的。我想在登录时设置 bash shell 函数并将其导出;所以我创建一个~/.profile
:
l() {
ls -la "$@"
}
export -f l
但是这个文件现在不会被 a 读取bash
,正如我所期望的,当/etc/passwd
声明我的登录 shell 是bash
.不,相反,它是由一个sh
(在我的例子中链接到dash
)读取的,并且它无法处理该export -f l
语句。
有没有办法让lightdm
//gnome
遵守compiz
我的登录 shell,/etc/passwd
而不是使用sh
?某处有这方面的配置吗?
答案1
作为最后的手段,您可以立即使用 覆盖它bash
。你.profile
可以从
read -r cmd rest < <(cat /proc/$$/cmdline | tr '\000' ' ')
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
exec /bin/bash "$rest"
fi
#... the rest of the .profile script
我相信它应该有效。稍微测试一下。
编辑:
以前的版本不起作用,因为$0
运行脚本的不是 bash,而是通常脚本的名称,并且$@
不包含正在运行的脚本的名称。这就是为什么从 获取原始命令行proc
,以实际完全重现命令行,但将第一个参数(shell)替换为 bash(如果还没有)bash
(删除if
,您将获得无限递归)。
笨拙的阅读是因为proc
使用空字符分隔符而不是空格而完成的,从而使我们的生活有点困难。但是不要紧。
父 shell 被覆盖,就像史密斯特工覆盖矩阵中的人一样。没有了dash
。的 PIDdash
及其中的所有内容都由 接管bash
。新的bash
重新运行脚本(但这次到达结束)。
我记得它.profile
没有作为参数传递给 bash,而是在初始化期间执行(来源)。您应该仔细检查您的具体情况。也许最好实际上强制exec /bin/bash --login
避免阅读命令行的麻烦。无论如何,登录 shell 应该会读取.profile
。
因此,最终的建议只是简单地说
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
exec /bin/bash --login
fi
从一开始就进入你的状态.profile
,看看会发生什么。理想情况下,如果登录 shell 已经是 bash,这应该没有什么区别,但应该用 bash 透明地覆盖任何其他 shell,而不会引起用户任何通知。