经过这次磨难后我还在使用 bash 吗?

Rob*_*ino 4 osx shell bash su shell-script

在 Mountain Lion 主机上Coguaro,我coconutpowder使用以下命令以用户身份登录bash

Coguaro:~ coconutpowder$ echo $0
-bash
Run Code Online (Sandbox Code Playgroud)

我需要以提升的权限运行命令,因此我尝试su切换到root但它不允许我:

Coguaro:~ coconutpowder$ su -
Password:
su: Sorry
Run Code Online (Sandbox Code Playgroud)

费够了。我阅读了该man页面su并得到了这个:

PAM is used to set the policy su(1) will use.
In particular, by default only users in the ``admin'' or ``wheel''
groups can switch to UID 0 (``root'').
Run Code Online (Sandbox Code Playgroud)

我注意到我不属于任何一个允许su这样做的群体:

Coguaro:~ coconutpowder$ id
uid=502(coconutpowder) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts)
Run Code Online (Sandbox Code Playgroud)

所以我重新运行su命令,并在其前面加上 a 前缀sudo,我可以按照如下方式执行此操作/etc/sudoers

/etc/sudoers: coconutpowder ALL=(ALL) ALL

Coguaro:~ coconutpowder$ sudo su -
Coguaro:~ root# echo $USER $0 $BASH_VERSION
root -sh 3.2.48(1)-release
Coguaro:~ root# 
Run Code Online (Sandbox Code Playgroud)

现在我遇到了一个我认为有问题的场景,因为我实际上正在运行sh我所看到的内容,这毕竟是我的登录 shell root,但是我从之前的登录中设置了环境变量,并通过该机制BASH_VERSION传递?sudo如果我错了请纠正我。

这意味着像这样的一些 shell 检测技巧会被破坏:

if [ ${BASH_VERSION-not_running_within_bash} = not_running_within_bash ]; then
  # ...
fi
Run Code Online (Sandbox Code Playgroud)

我完全不知道如何正确su使用root并有某种方法确定我是否bash正在使用。该脚本广泛使用 Bash 数组,如果某些值出现错误,可能会破坏文件系统路径。我发现ps -p $$其他地方提到的黑客有点黑客(?!),所以我正在寻找完成我想要完成的任务的最佳方法,考虑到我必须首先登录,coconutpowder而不能直接这样做root

如果我错误地进行了用户切换,我相信这个问题与其他仅检测当前(不是“默认”“分配”)shell 的问题截然不同。

到目前为止,我正准备解析 $0,可能会删除任何表示-登录 shell 的前缀字符。

除非你们中的任何人都可以教我如何su登录(即阅读 $HOME/.profile)并直接从默认值root切换到默认值,这是无法更改的。bashsh

Jim*_*ris 5

现在我遇到了一个我认为有问题的场景,因为我实际上正在运行 sh 来查看我所看到的内容,毕竟这是我的 root 登录 shell,但是我从之前的登录中设置了 BASH_VERSION 环境变量,并通过 sudo 传递机制?如果我错了请纠正我。

幸运的是,你错了。和BASH_VERSION类似的环境变量已设置,但未导出,因此子进程不存在它们。

比较输出:

set | grep ^BASH
Run Code Online (Sandbox Code Playgroud)

env | grep ^BASH
Run Code Online (Sandbox Code Playgroud)

setenv显示环境变量。 set是一个内置的 shell,它可以看到BASH_*变量。 env是一个外部程序,您会注意到它BASH_*根本看不到变量。

如果您确实想将这些变量导出到子进程,您可以手动执行此操作,然后它将显示在env

$ export BASH_VERSION
$ env | grep ^BASH
BASH_VERSION=4.2.36(1)-release
Run Code Online (Sandbox Code Playgroud)

但除非您像这样手动导出它们,否则您可以相当确定 的存在BASH_VERSION意味着您实际上正在运行 bash。另请参阅 的输出,export -p了解哪些变量将以这种方式导出。