先说下这问题咋来的,目前开发流程如下:


+---------------+ scp files... +-----------------+
| localhost | ===================================> | remote host |
| for coding | remote ssh command for compiling | for compiling |
+---------------+ +-----------------+

如上图,代码是本地马吊们敲出来地,so文件是要放到远程开发环境编译出来地;
普通青年尼,可能是打开xshell,xftp,先把文件拖上去,然后ssh登陆编译环境,然后make;
效率极低不说,逼格也不够啊,于是乎就有了下面代码:

scp *$1*.{gcc,h,pc,cpp} ya-dev:~/src
ssh ya-dev 'cd ~/src; ls '"*$1*"'.gcc | xargs -I {} make -f {} ORA_VER=10'

问题来了,远程执行会报错,部分lib库找不到;但是ssh登陆后再执行就没问题~
ssh ya-dev env 一看,果然缺少很多环境变量,为什么会这样呢,这就要从爷爷粮票的故事讲起了~

Shell modes

主要有以下两种模式

login

  • 你打开一个shell或者terminal,提示输入用户名密码才能登陆,这就是个login shell
  • 如果你打开terminal就能直接用,那non-login shell(Mac OSX特殊一些)
  • 总玩ubuntu的应该知道,Ctrl + Alt + F1 出来的就是个login shell

interactive

  • 你打开的shell有prompt,并且它的stdin、stderr都定向到terminal
  • 上面那是术语,名字就能看出来,互动嘛,你通过ssh登录远程机器,ssh server肯定要给你个pty吧,好让你执行命令

Test

me@local-mac$  `[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'`
Interactive
me@local-mac$ `shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'`
Login shell # 特殊 for mac osx

me@local-mac$ `ssh ubuntu "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"`
Interactive # 因为我用的terminal是interactive
me@local-mac$ `ssh ubuntu "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"`
Not login shell

me@local-ubuntu$ `[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'`
Interactive
me@local-ubuntu$ `shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'`
Not login shell # 有别于mac osx

me@local-mac$ `bash test.sh`
Not interactive # bash script.sh:non-login,non-interactive; 说明ssh remote command 是 non-login,non-interactive
me@local-mac$ `cat test.sh`
ssh ubuntu "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"

Shell init files

how the bash load init files

Answer

回到开篇问题,为什么少了很多环境变量那,从上图可以看出,俺的脚本是non-login,non-interactive
所以.bash_profile,.bashrc都没被执行到~

  1. 用到的变量都加到/etc/environment中,这个就是全局了,如果你不想影响其他用户,请看下一方法
  2. sshd_config配置项PermitUserEnvironment
    • vim /etc/sshd_config, add 'PermitUserEnvironment yes'
    • 添加变量到~/.ssh/environment
    • service ssh restart
    • ssh remote env 测试一下
  3. $BASH_ENV
    • 这个变量默认是空值,在哪有效设置让我有些迷惑
    • 你想想,放到/etc/enviroment里吧,不如直接方法1了
    • 放到~/.bash_profile ~/.bashrc里吧,就像之前说的,是读取不到的
    • google到一方法,通过crontab来解决

Reference