【问题标题】:How to get the default shell如何获取默认外壳
【发布时间】:2013-04-28 20:05:55
【问题描述】:

我们可以运行类似chsh -s /usr/local/bin/zsh 的东西来设置一个新的默认shell。有没有我们可以运行的命令来知道那个 shell 是什么?

我的意思不是打开终端并运行命令来知道我们在哪个 shell。我的意思是像上面的例子一样,如果我在一个打开 /bin/bash 的终端中,我应该运行什么获取/usr/local/bin/zsh,如果它是当前的默认shell?

【问题讨论】:

  • 另外,请记住 unix.stackexchange.com 的存在 :)
  • 不,这是关于 current shell 而不是用户的 default shell。

标签: macos shell


【解决方案1】:

您可以使用以下命令:

echo $SHELL

【讨论】:

  • 请记住,SHELL 可能不会被所有 shell 设置,并且不能保证所有 shell 使用相同的规则来设置其值。
  • @chepner SHELL 变量是标准的。它不是由 shell 本身设置的,而是在登录进程启动 shell 之前设置的。
  • 这不起作用。 SHELL 不显示默认外壳。此信息存储在 /etc/passwd 中。或者对于 Mac 使用:dscl . -read /Users/username UserShell(感谢 Lri 提供信息)
  • @Bill 没错,当前登录 shell 与默认 shell 不同。阅读linuxg.net/the-unix-and-linux-shell-variable-shell 它说“$SHELL 是产生当前会话的父shell”。它不等于 chsh 设置的默认 shell
  • 虽然$SHELL 一个标准,并且它对某些事情很有用,但我认为它不是这个特定问题的合适答案。 系统默认 shell, 用户的 默认 shell(这个问题问的是什么), current shell(很多人认为$SHELL be)和“首选的命令语言解释器”($SHELL实际上是)都非常不同。任何假定$SHELL 是(或应该是)等价于当前用户最后传递给chsh 的字符串的脚本都不会在用户间移植,更不用说系统间移植了,除了运气好。
【解决方案2】:

对于 macOS:

dscl . -read /Users/username UserShell

对于当前的 macOS 用户:

dscl . -read ~/ UserShell

使用sed解析路径内联:

dscl . -read ~/ UserShell | sed 's/UserShell: //'

使用$SHELL 将报告当前的登录shell,而不是默认的登录shell。在某些情况下,这些并不相同。例如,在 Visual Studio Code 等 IDE 中工作时,它会打开集成终端而不咨询默认 shell。

另外,正如 Martin C. Martin 所指出的,$SHELL 是一个常量,chsh 更改默认登录 shell 后不会更改。

【讨论】:

  • 我在 macOS 上。尽管您的代码也可以工作,但echo $SHELL 在各方面都更胜一筹。它运行速度更快,需要的 CPU 更少,更短,更通用。
  • @user137369 如果您从 shell 中调用 chsh,它无法更新 $SHELL。所以echo $SHELL 报告旧值,现在不正确,但dscl . -read /Users/$USER UserShell 报告新值。
  • @user137369,同样如果你登录然后运行zsh --login,那么 $SHELL 不一定与你的登录 shell 相同。这个答案是正确的。
【解决方案3】:

您可以在 /etc/passwd 文件中 grep 获取当前用户名,并使用 cut 提取相应的信息列:

grep ^$(id -un): /etc/passwd | cut -d : -f 7-

$(id -un)$USER 更安全地获取用户名。在用户名前使用^,在用户名后使用:,确保您的用户名是其他用户名的子部分时不会出现错误匹配。

$SHELL 也可以按照建议使用。但是,如果在当前 shell 中使用了chsh,它将不起作用,因为变量没有更新。此外,该变量不受保护以防止被更改,因此理论上可以将其设置为完全不同的值。

更新以尝试兼容 OS X 的解决方案。可能不是最佳的正则表达式:

grep ^.*:.*:$(id -u): /etc/passwd | cut -d : -f 7-

这是基于用户 ID 的。如果整个用户条目丢失,不仅是用户名,那么 osx 必须将其存储在其他地方。

【讨论】:

  • 哪一部分在 OSX 上不起作用?访问 /etc/passwd 以获取默认 shell,或者获取周围的东西以提取用户名和所需的部分信息?
  • 由于某种原因,/etc/passwd 中没有我的用户帐户名称。
  • OS X doesn't include normal user accounts in /etc/passwd。你也可以使用dscl . -read /Users/username UserShell
  • 代替 grep 和 cut(它们实际上只是 awk 的子集),如果可用,您也可以只使用 awk 本身:awk -F: '$1==u{print $7}' u=$(id -un) /etc/passwd 两个子进程(awk 和 id)而不是三个。 :)
【解决方案4】:

如果你想得到一个用户的默认shell,你可以grep文件/etc/passwd。喜欢:

grep "$USER" /etc/passwd

# kent:x:1000:1000::/home/kent:/bin/zsh

告诉我当前用户 (kent) 有默认的 shell /bin/zsh

如果你只是想抓住外壳部分:

awk -F: -v u="$USER" 'u==$1&&$0=$NF' /etc/passwd

# /bin/zsh

如果要获取其他用户的默认shell,只需替换$USER部分即可。

【讨论】:

  • @user137369:OS X 不使用 /etc/password(启动期间除外),它将用户保留在 /var/db/dslocal/nodes/Default/users/$USER.plist 中(其中不可读,除非root)。对于网络域中定义的任何用户或任何其他非/etc/password 源,此方法在其他操作系统上也将失败。顺便说一句,在 OS X 上,您可以使用 dscl /Search -read "/Users/$USER" UserShell | awk '{print $2}',但这在其他任何地方都行不通。
  • 如果我的回答误导了某人,我很抱歉。我对 OS X 没有任何经验。
【解决方案5】:

在 OS X 中,使用命令 env | grep -i 'SHELL' 会产生如下输出:SHELL=/bin/sh (作为 root,但是普通用户倾向于将 /bin/bash 作为默认 shell)通过一点解析,可以轻松识别和提取 shell 的路径(以及 shell 本身)。..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2014-02-25
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2017-08-14
    相关资源
    最近更新 更多