不论是在学校里还是在公司中,远程登录服务器调试是一件很平常的事情。通过服务器,我们有很多种方式进行开发,喜欢极客风的可以直接通过Vim在服务器中进行开发,配合各种插件在开发效率上还是很高的;另一种就是利用IDE远程连接服务器进行调试,这样可以借助一些IDE的强大功能,提升自己的开发效率(Pycharm、VSCODE)。
在利用Pycharm进行远程调试过程中,在配置好远程解释器后,运行代码是通过SSH直接执行的方式,远程进行命令和脚本调试。
这种方式会使用Bash的non-interactive + non-login shell模式,会创建一个shell,执行完脚本之后便退出,不再需要与用户交互。
假设我们运行时出现找不到动态链接库的问题:
ssh://oldpan@176.32.12.18:22/home/oldpan/anaconda3/envs/pytorch/bin/python -u /data/oldpan/code/CenterNet/src/demo.py Traceback (most recent call last): File "/data/oldpan/code/CenterNet/src/demo.py", line 11, in <module> from detectors.detector_factory import detector_factory File "/data/oldpan/code/CenterNet/src/lib/detectors/detector_factory.py", line 5, in <module> from .exdet import ExdetDetector File "/data/oldpan/code/CenterNet/src/lib/detectors/exdet.py", line 21, in <module> from .base_detector import BaseDetector File "/data/oldpan/code/CenterNet/src/lib/detectors/base_detector.py", line 11, in <module> from models.model import create_model, load_model File "/data/oldpan/code/CenterNet/src/lib/models/model.py", line 12, in <module> from .networks.pose_dla_dcn import get_pose_net as get_dla_dcn File "/data/oldpan/code/CenterNet/src/lib/models/networks/pose_dla_dcn.py", line 16, in <module> from .DCNv2.dcn_v2 import DCN File "/data/oldpan/code/CenterNet/src/lib/models/networks/DCNv2/dcn_v2.py", line 13, in <module> import _ext as _backend ImportError: libcudart.so.10.0: cannot open shared object file: No such file or directory
这种问题,如果是在服务器终端中,可以直接在bash_profile中加入了export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
,然后source一下,指定了程序执行时的动态链接库寻找路径。
而Pycharm这种是no-login shell,可以看到上面的命令有些不一样ssh://oldpan@176.32.12.18:22/home/oldpan/anaconda3/envs/pytorch/bin/python
这个任务不是在登录Linux系统时启动的(比如你在命令行提示符上输入bash启动),因此不会执行/etc/profile文件,而会去用户的HOME目录检查.bashrc并加载。系统执行Shell脚本的时候,就是属于这种non-interactive shell。Bash通过BASH_ENV环境变量来记录要加载的文件,默认情况下这个环境变量并没有设置。如果有指定文件,那么Shell会先去加载这个文件里面的内容,然后再开始执行Shell脚本。
解决方法
这个时候修改bash_profile
不起作用,需要修改当前用户HOME目录下的.bashrc
,添加需要的环境变量即可。
而bash_profile
是在我们通过SSH登录后再执行的命令和脚本,这种方式会使用Bash的interactive + login shell模式,这里面有两个概念需要解释:interactive和login。
login故名思义,即登陆,login shell是指用户以非图形化界面或者以ssh登陆到机器上时获得的第一个shell,简单些说就是需要输入用户名和密码的shell。因此通常不管以何种方式登陆机器后用户获得的第一个shell就是login shell。
interactive意为交互式,这也很好理解,interactive shell会有一个输入提示符,并且它的标准输入、输出和错误输出都会显示在控制台上。所以一般来说只要是需要用户交互的,即一个命令一个命令的输入的shell都是interactive shell。而如果无需用户交互,它便是non-interactive shell。通常来说如bash script.sh此类执行脚本的命令就会启动一个non-interactive shell,它不需要与用户进行交互,执行完后它便会退出创建的Shell。
在interactive + login shell模式中,Shell首先会加载/etc/profile文件,然后再尝试依次去加载下列三个配置文件之一,一旦找到其中一个便不再接着寻找:
~/.bash_profile
~/.bash_login
~/.profile
参考文章
https://blog.csdn.net/luyinchangdejiqing/article/details/95726738