主机 win10,虚拟机 ubuntu20.4,用plink能成功连接并运行 python 代码,但环境变量(PATH,PYTHONPATH)不对。应该是没有 source ~/.bashrc
。/etc/profile, /etc/bash.bashrc 都设置了,不起作用。有没有哪位大佬指导下怎么设置。
在手册上找到种方法,手工设置环境变量暂时解决了。
(add-to-list 'tramp-remote-process-environment "JAVA_HOME=/opt/java")
但手册中提到的设置 (setenv “ENV” “$HOME/.profile”) 的方法不起作用。
经大佬提醒,手册中完整的是:
Setting the
ENV
environment variable instructs some shells to read an initialization file. By default, TRAMP disables this. You can override this behavior by evaluating
(let ((process-environment tramp-remote-process-environment))
(setenv "ENV" "$HOME/.profile")
(setq tramp-remote-process-environment process-environment))
引用代码的时候应该严谨一些。你这么写,我可能会认为:
- 你在代码里把引号写错了。
- 你这句代码放的位置不对。
谢谢提醒,已经修改。
看了下 bash 的参数有 -norc -noprofile。但去掉 -norc后连不上,原因未知。
怎么认定「不起作用」?你用什么方法/步骤观察?
$ emacs -Q --eval '
(let ((default-directory "/ssh:user@host:"))
(message "==> %s" (shell-command-to-string "echo $VAR_IN_PROFILE")))' --batch
Tramp: Sending command ‘exec ssh -o ControlMaster=auto -o ControlPath=tramp.%C -o ControlPersist=no -e none user@host’
Tramp: Found remote shell prompt on ‘user@host’
==> Value of VAR_IN_PROFILE
我是在python中直接打印环境变量发现的:
import os
print(os.environ["PATH"])
print(os.environ["ENV"])
print(os.environ["TERM"])
print(os.environ["PYTHONPATH"])
输出:
-*- mode: compilation; default-directory: "/plink:hadoop@ubuntu:~/test/" -*-
Compilation started at Wed Mar 29 14:23:04
python3 a.py
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
~/.profile
dumb
Traceback (most recent call last):
File "a.py", line 7, in <module>
print(os.environ["PYTHONPATH"])
File "/usr/lib/python3.8/os.py", line 675, in __getitem__
raise KeyError(key) from None
KeyError: 'PYTHONPATH'
Compilation exited abnormally with code 1 at Wed Mar 29 14:23:04
~/.profile 中设置了环境变量了,服务器上输出(ENV,没设,服务器上注释掉了):
hadoop@hh:~/test$ python3 a.py
/usr/lib/jvm/java-11-openjdk-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/spark/hadoop/sbin:/opt/spark/hadoop/bin:/opt/spark/hadoop/sbin:/opt/spark/hadoop/bin
xterm
/opt/spark/spark/python/lib/py4j-0.10.9.5-src.zip:/opt/spark/spark/python/lib/pyspark.zip:/opt/spark/spark/python/lib/py4j-0.10.9.5-src.zip:/opt/spark/spark/python/lib/pyspark.zip:/opt/spark/spark/python/lib/py4j-0.10.9.5-src.zip:/opt/spark/spark/python/lib/pyspark.zip:/opt/spark/spark/python/lib/py4j-0.10.9.5-src.zip:/opt/spark/spark/python/lib/pyspark.zip:
你试运行一下我前面提供的脚本。
确认一下远程主机的 profile 启动顺序,各个系统有差别。有的可能不执行 .profile
,换 .bash_profile
或 .bashrc
试试。
大佬,运行不了,我才手动用 Emacs -Q的, 就是上面那个截图。启动后没做别的,就只把 plink 加进emacs 的 path,然后才能用 tramp plink 连接 linux。
运行你给的脚本有个概念没搞懂,怎么输入密码?放 .netrc 文件似乎不行。
- 在 msys 下运行:
$ emacs -Q --eval '(let ((default-directory "/ssh:[email protected]:")) (message "==> %s" (shell-command-to-string "echo $PATH")))' --batch
Tramp: Sending command `ssh -l hadoop -e none 192.168.43.172 && exit || exit'
File error: Tramp failed to connect. If this happens repeatedly, try
`M-x tramp-cleanup-this-connection'
Tramp failed to connect. If this happens repeatedly, try
`M-x tramp-cleanup-this-connection'
lld@Win10-2022HSFQW MINGW64 ~
$
- 在windows命令行下运行:
C:\Users\lld>emacs -Q --eval '(let ((default-directory "/plink:[email protected]:")) (message "==> %s" (shell-command-to-string "echo $PATH")))' --batch
Error: end-of-file nil
debug-early-backtrace()
debug-early(error (end-of-file))
command-line-1(("--eval" "'(let" "((default-directory" "/plink:[email protected]:))" "(message" "==> %s" "(shell-command-to-string" "echo $PATH)))'"))
command-line()
normal-top-level()
End of file during parsing
如果你在 ~/.ssh/config
设置了 IdentityFile,就可以免密。如果没有设置,就会询问密码:
$ emacs -Q --eval '
(with-current-buffer (find-file-noselect "/ssh:[email protected]:~/.profile")
(message "==> %S" (shell-command-to-string "echo $loaded")))' --batch
Tramp: Sending command ‘exec ssh -l root -o ControlMaster=auto -o ControlPath=tramp.%C -o ControlPersist=no -e none 192.168.1.1’
Tramp: Sending password
Password for /ssh:[email protected]: ▋
(connection-local-set-profile-variables
'remote-bash
'((explicit-shell-file-name . "/bin/bash")
(explicit-bash-args . ("-i"))
))
(connection-local-set-profiles
'(:application tramp :protocol "plink" :user "xxxx" :machine "xxxx")
'remote-bash)
是否免密不是重点。
你的问题是环境变量没有生效。如我前面所说,你应该看看远程主机是什么系统和shell,是加载 .bash_profile
还是 .profile
。如果 tramp 登录有问题,ssh 直接登录应该也有问题:
找到了解决办法,加载的是 .bashrc
文件。
要点1:将 tramp-own-remote-path
加进 tramp-remote-path
要点2:覆盖默认的 命令行参数,用 (explicit-bash-args . ("-i"))
(with-eval-after-load 'tramp
(add-to-list 'tramp-connection-properties
(list (regexp-quote "/plink")
"remote-shell" "/bin/bash"))
(connection-local-set-profile-variables
'remote-bash
'((explicit-shell-file-name . "/bin/bash")
(explicit-bash-args . ("-i"))
))
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
补充一下,执行完后记得 tramp-cleanup-all-connections
然后再试一下 (executable-find "your-program" t)
试试看能不能找到远端的应用程序。
我觉得 tramp-remote-path
真该默认包含 tramp-own-remote-path
我也觉得应该包含。通过 tramp-remote-process-environment
的方式用了好久。
(add-to-list 'tramp-remote-process-environment
(format "PYTHONPATH=%s" (getenv "PYTHONPATH_REMOTE")))
直接ssh,配置可行,但经过跳板机ssh,试验失败,请问跳板机下如何配置
打开日志,tramp-verbose 设置成6看下哪里报错。
我用过 Windows->SUSE->SUSE是可以读取到bashrc的。中间SUSE我是直接加进 第三跳的authorized_keys