我在 Mac OS Big Sur 上运行虚拟 Ubuntu 16.04 Linux 实例(使用 vagrant)。我可以很好地运行以下两个命令(一个用于 ssh 进入虚拟服务器,第二个用于在其中运行命令)......
$ ssh myvirtual.local
Warning: Permanently added '10.0.4.19' (ECDSA) to the list of known hosts.
Last login: Wed Sep 15 16:37:57 2021 from 10.0.4.1
$ foreman start -f Procfile.debug
16:38:26 rails.1 | started with pid 27884
16:38:26 worker.1 | started with pid 27885
16:38:26 scheduler.1 | started with pid 27887
...
我希望能够将这两个命令结合起来,所以我尝试了
$ ssh -t myvirtual.local 'foreman start -f Procfile.debug’
Warning: Permanently added '10.0.4.19' (ECDSA) to the list of known hosts.
bash: foreman: command not found
Connection to 10.0.4.19 closed.
我很困惑我需要运行什么其他设置才能有一个命令来模拟我最初正在做的事情。有什么想法吗?
在这种情况下的主要区别在于,
ssh host
以登录模式启动您的登录 shell(以在其前面添加它来sshd
启动它,这告诉 shell 它必须通过读取一个, , ,或(可能还有系统中的)启动脚本来初始化登录会话,具体取决于在 shell 实现上)和交互方式(因为它发出提示以获取您的输入)。就是这种模式。-
argv[0]
.profile
.bash_profile
.zprofile
.zlogin
.login
/etc
rlogin
ssh
在 中时
ssh -t host 'some shell code'
,使用and作为参数sshd
运行您的登录 shell,但不告诉它是登录 shell。该外壳也是非交互式的,代码不会从终端提示您。这就是模式。-c
some shell code
rsh
在您的情况下,很可能找不到该命令,因为会话初始化文件中设置
$PATH
变量的某些指令尚未运行。请注意,并非所有 shell 都可以作为登录 shell 并解释作为参数给出的代码。
bash
外壳可以。当它开始bash
时将作为登录 shell启动,但在传递一个or选项时也会启动,然后即使传递了一个要执行的命令(POSIX 模式除外),then1¹ 仍将读取登录会话初始化文件。argv[0]
-
-l
--login
-c
所以在这里,而不是这样做:
你可以这样做:
这将启动另一个.
bash
_ _~/.bash_profile
/etc/profile
/etc/profile.d
$PATH
some code
或者您可以尝试找到进行
$PATH
定义的文件并执行以下操作:这仍然留下了另一个区别,即 shell 不是交互式的,并且您的启动文件可能会决定在交互时的行为与非交互时的行为不同(通过检查 in 的存在
i
或$-
检查$PS1
变量的存在)。bash
当作为登录 shell 运行时,即使在交互时(与大多数其他 shell 中发生的情况相反),在启动时也不会解释~/.bashrc
(交互式 shell 自定义文件),但大多数人通过source ~/.bashrc
在他们的~/.bash_profile
. 默认情况下~/.profile
,Debian 和衍生产品上的默认设置是这样做的(当然只有当 shell 是这样bash
时)。bash
默认情况下通过 ssh 调用时不会解释~/.bashrc
,但可以在编译时使用SSH_SOURCE_BASHRC
配置选项进行配置。Debian 和 Ubuntu 等衍生产品确实可以做到这一点。因此,在执行时ssh ubuntu-host 'some code'
,如果您的登录 shell 是该机器上的 bash ,则将启动的bash
shell将在解释之前解释。sshd
~/.bashrc
some code
~/.bashrc
最终以rlogin
and模式解释也是如此rsh
,但正如@Quasimodo 所指出的,~/.bashrc
Debian 和 Ubuntu 的默认设置在顶部:所以,如果
$PATH
在这些行下面有一个定义,它们只会在rlogin
模式中解释(bash
交互的地方,$-
包含i
和~/.bashrc
来源~/.profile
),而不是rsh
模式(~/.bashrc
来源,但它的大部分内容被跳过为外壳不是交互式的)。¹ 在以
argv[0]
开头-
(与以-l
/相对--login
)的情况下,传递 a 时是否将其视为登录 shell-c code
取决于是否已启用bash
编译。NON_INTERACTIVE_LOGIN_SHELLS
您缺少环境设置,因为这两种情况并不总是相同的:
下一个命令块将为您提供首选解决方案中缺少的变量集(上面两个示例中的第二种格式)。您可以将这些添加到您的问题中,我将完成这个以解释如何设置它们,或者您可以自己使用这些信息来设置它们。
我在这里拥有的系统的缩写示例输出
这没有任何特定于 Ruby 或 Rails 的内容,但它确实表明在我的情况下
PATH
变量是不同的(您将能够在/tmp/env.1
和中看到实际值/tmp/env.2
)。一旦你对它进行了跟踪和排序,你可能想要
foreman
在screen
or下运行,这样当连接终止时tmux
它就不会收到SIGHUP
信号。ssh
但我建议您先解决最初的问题,然后再引入这些附加工具中的任何一个。