我有一个类似于这个问题的环境:用于交互式和非交互式工作的不同 shell
我目前坚持使用 tcsh 作为我的“官方”默认 shell。对于交互式 shell,我基本上exec /bin/bash
来自我的~/.login
文件。
有没有办法让 bash 成为非交互式 shell 的 shell?即,如果我这样做,ssh myserver env
它会打印出 shell 是/bin/tcsh
.我看着~/.cshrc
,我看到了在哪里我可以在里面放一些东西来做到这一点,但我不知道什么放在那里。或者也许有一个不同的地方可以放置这样的东西?
目前,如果我exec /bin/bash
使用~/.cshrc
非交互式 shell,上面的 ssh 命令将挂起(大概是因为它试图从非交互式 shell 执行交互式 shell)。
甚至有可能做我想做的事吗?
答案1
如果您的远程计算机是 Linux,请尝试将其添加到您的~/.tcshrc
:
if ($?SSH_CONNECTION && $shlvl == 1) then
set sh = /bin/bash
set cmdline = "`tr '\0\n' '\n\1' </proc/$$/cmdline`"
if ($#cmdline > 2) then
exec $sh -c 'exec "$0" -c "$(printf %s "$1" | tr "\1" "\n")"' $sh $cmdline[3]:q
endif
endif
当您调用 时ssh user@host cmd
,ssh 服务器基本上所做的就是调用user
with的登录 shell-c
并将cmd
其作为参数传递给它。如果您仅从exec /bin/bash
您的调用~/.cshrc
,则 bash 将在不带参数的情况下调用,并期望从其标准输入读取命令,这意味着它将ssh user@host cmd
显示为“挂起”,直到您按 Ctrl-C 或 Ctrl-D。
上面的 kludge 尝试cmd
从中获取参数/proc/<pid>/cmdline
,然后/bin/bash
以相同的方式调用您选择的 shell ( ),并将-c
和cmd
作为参数传递给它。它假定\1
中不存在 ASCII 控制字符 (Ctrl-A)cmd
。这和大多数并发症都是由于试图在 中保留换行符cmd
,而且我根本不确定我是否做对了;-)
欢迎改进(和简化!)。
答案2
您可以添加到您的~/.ssh/authorized_keys
:
command="setenv SHELL \"`which bash\"`; if ($?SSH_ORIGINAL_COMMAND) eval 'exec bash -c $SSH_ORIGINAL_COMMAND:q'; exec bash -l" your-pub-key-here
当您使用该密钥进行 ssh 登录时,强制运行由您的登录 shell ( tcsh
) 解释的命令行,而不是所请求的命令。如果传递了命令行,它将在$SSH_ORIGINAL_COMMAND
环境变量中可用,我们告诉bash
执行它,如果没有,我们只需将 bash 作为登录 shell 启动。
我们设置$SHELL
的路径bash
告诉在 ssh 会话中启动的应用程序是bash
您的首选 shell,而不是 tcsh 您的登录 shell。