SSH远程连接时环境变量问题

简介:

1. 问题

RHEL服务器A有个启动脚本(普通用户user01运行),里面使用ifconfig获取ip地址如下:

Localhost_ip=$(ifconfig |awk -F 'addr:|Bcast' '/Bcast/{print $2}')

由于普通用户user01不能直接识别ifconfig命令,只能使用全路径/sbin/ifconfig,目前处理方式为修改~/.bash_profile文件添加环境变量如下:

PATH=$PATH:$HOME/bin

改成如下:

PATH=$PATH:$HOME/bin:/sbin

经过如上配置后服务器本机user01用户登录执行XX.sh脚本可以识别ifconfig命令。

出现如下问题:

远程主机B通过ssh远程执行启动脚本XX.sh,报错如下:

bash: ifconfg: command not found

2. 问题分析

测试前准备,追加调用说明语句,如下:

/etc/profile
[root@node3 ~]# vim /etc/profile
echo "/etc/profile begin:"
echo "$PATH"
...
 
unset i
unset pathmunge
 
echo "invoke /etc/profile"
echo "$PATH"
echo ""
[root@node3 ~]# vim /etc/bashrc
...
# vim:ts=4:sw=4
 
echo "invoke /etc/bashrc"
echo "$PATH"
echo ""
[root@node3 ~]# vim /root/.bash_profile
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
 
echo "invoke ~/.bash_profile"
echo "$PATH"
echo ""
[root@node3 ~]# vim /root/.bashrc
...
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
 
echo "invoke ~/.bashrc"
echo "$PATH"
echo ""
[root@node3 ~]# vim /home/user01/.bash_profile
...
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
 
echo "invoke ~/.bashrc"
echo "$PATH"
echo ""
[root@node3 ~]# vim /home/user01/.bashrc
...
# User specific aliases and functions
 
echo "invoke ~/.bashrc"
echo "$PATH"
echo ""

分 user 和 root 用户,3 种场景进行测试,如下:

普通用户 User

场景1:

本机使用 su 命令切换到普通用户 (属于 Login 方式)

结论:

  • Login 之前,系统 PATH 为:/usr/local/bin:/bin:/usr/bin
  • Login 方式,文件调用顺序为: /etc/profile -> /etc/bashrc -> ~/.bashrc -> ~/.bash_profile
  • Login 之后,系统 PATH 为:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/user01/bin
su - user
[root@node3 ~]# hostname -i
192.168.122.33
[root@node3 ~]# su - user01
/etc/profile begin:
/usr/local/bin:/bin:/usr/bin
invoke /etc/profile
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke /etc/bashrc
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke ~/.bashrc
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke ~/.bash_profile
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/user01/bin

场景2:

远程机使用 ssh 命令以普通用户身份登陆到主机 (属于 Login 方式)

结论:

  • 与在本机使用 su 命令切换到普通用户的效果完全一样!
ssh user@remote_server_ip
[root@node1 ~]# hostname -i
192.168.122.31
[root@node1 ~]# ssh user01@192.168.122.33
user01@192.168.122.33's password: 
Last login: Tue Jul  9 16:23:33 2013 from 192.168.122.31
/etc/profile begin:
/usr/local/bin:/bin:/usr/bin
invoke /etc/profile
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke /etc/bashrc
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke ~/.bashrc
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
 
invoke ~/.bash_profile
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/user01/bin

场景3:

远程机使用 ssh 命令以普通用户身份连接到主机执行获取 PATH 的命令 (属于 NoLogin 方式)

结论:

  • NoLogin 方式,命令获取的 PATH 为该远程机的,并未拿到目标主机的 PATH
  • NoLogin 方式,文件调用顺序为:/etc/bashrc -> ~/.bashrc
  • NoLogin 方式,目标主机 User 用户 PATH 为:/usr/local/bin:/bin:/usr/bin
ssh user@remote_server_ip command
[root@node1 ~]# hostname -i
192.168.122.31
[root@node1 ~]# echo $PATH
/usr/local/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
 
[root@node1 ~]# ssh user01@192.168.122.33 "echo $PATH"
user01@192.168.122.33's password: 
 
invoke /etc/bashrc
/usr/local/bin:/bin:/usr/bin
 
invoke ~/.bashrc
/usr/local/bin:/bin:/usr/bin
 
/usr/local/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

对比 root 用户

场景1:

本机使用 su 命令切换到 root (属于 Login 方式)

结论:

  • Login 之前,系统 PATH 为:/usr/local/bin:/bin:/usr/bin
  • Login 方式,root 用户,文件调用顺序为:/etc/profile -> /etc/bashrc -> ~/.bashrc -> ~/.bash_profile
  • Login 之后,系统 PATH 为:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
su - root
[root@node3 ~]# hostname -i
192.168.122.33
[root@node3 ~]# su - root
/etc/profile begin:
/usr/local/bin:/bin:/usr/bin
invoke /etc/profile
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke /etc/bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke ~/.bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke ~/.bash_profile
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

场景2:

远程机使用 ssh 命令以 root 用户身份登陆到主机 (属于 Login 方式)

结论:

  • 与在本机使用 su 命令切换到 root 用户的效果完全一样!
ssh root@remote_server_ip
[root@node1 ~]# hostname -i
192.168.122.31
[root@node1 ~]# ssh root@192.168.122.33
root@192.168.122.33's password: 
Last login: Tue Jul  9 15:54:53 2013 from 192.168.122.1
/etc/profile begin:
/usr/local/bin:/bin:/usr/bin
invoke /etc/profile
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke /etc/bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke ~/.bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke ~/.bash_profile
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

场景3

远程机使用 ssh 命令以 root 用户身份连接到主机执行获取 PATH 的命令 (属于 NoLogin 方式)

结论:

  • NoLogin 方式,命令获取的 PATH 为该远程机的,并未拿到目标主机的 PATH
  • NoLogin 方式,文件调用顺序为:/etc/bashrc -> ~/.bashrc
  • NoLogin 方式,目标主机 root 用户 PATH 为:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
ssh root@remote_server_ip command
[root@node1 ~]# hostname -i
192.168.122.31
[root@node1 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
 
[root@node1 ~]# ssh root@192.168.122.33 "echo $PATH"
root@192.168.122.33's password: 
invoke /etc/bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
invoke ~/.bashrc
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

关于/etc/profile 文件部分代码分析

结论:

  • 无论 root 还是 user ,只有调用此文件,其 PATH 中才会被追加 sbin 相关路径。而由以上测试场景可知,只有 Login 时,/etc/profile 文件才会被调用。
pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}

if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`id -u`
        UID=`id -ru`
    fi
    USER="`id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi


# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /sbin
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
    pathmunge /sbin after

fi

3. 总结

综上,如需修改 PATH,建议修改 bashrc 文件,从而保证任何方式访问时 PATH 的正确性。

目录
相关文章
|
2月前
|
网络协议 网络安全
ssh远程连接不上
ssh远程连接不上
42 0
|
2月前
|
Ubuntu 网络协议 网络安全
如何在外SSH远程连接Ubuntu系统【无公网IP】
如何在外SSH远程连接Ubuntu系统【无公网IP】
113 0
|
2月前
|
网络协议 IDE 网络安全
GoLand远程开发IDE:使用SSH远程连接服务器进行云端编程
GoLand远程开发IDE:使用SSH远程连接服务器进行云端编程
352 0
|
9月前
|
网络协议 Shell 网络安全
在外SSH远程连接macOS服务器【cpolar内网穿透】
macOS系统自带有Secure Shell 客户端,它可让您登录到侦听传入SSH连接的远程服务器和台式机。我们可以用ssh username@ip来ssh到服务器,但通常局限于局域网内的远程。
90 0
|
2月前
|
Linux 网络安全 数据安全/隐私保护
SSH - 远程连接中遇到的两个坑与SSH
SSH - 远程连接中遇到的两个坑与SSH
44 0
|
9月前
|
网络协议 Ubuntu 网络安全
使用VScode SSH公网远程连接本地服务器开发【无公网IP内网穿透】
使用VScode SSH公网远程连接本地服务器开发【无公网IP内网穿透】
|
26天前
|
网络协议 安全 Linux
在IntelliJ IDEA中使用固定公网地址远程SSH连接服务器环境进行开发
在IntelliJ IDEA中使用固定公网地址远程SSH连接服务器环境进行开发
39 2
|
1月前
|
运维 Linux 网络安全
跨平台SSH文件传输:Linux与Windows环境下的实践指南
本文介绍了在Linux和Windows之间使用SCP、SecureCRT及PuTTY工具集进行文件传输的方法。在Linux中,利用SCP命令进行文件下载、上传及目录传输。在Windows环境下,PSFTP和PSCP提供类似功能,而SecureCRT作为SSH客户端,支持设置上传下载目录并进行文件传输。掌握这些工具的使用可提升跨平台运维效率。
|
1月前
|
网络协议 网络安全 数据安全/隐私保护
如何在IDEA中使用固定公网地址SSH远程连接服务器开发环境(三)
在IDEA中通过固定公网地址SSH远程连接服务器开发环境,需要配置固定TCP端口以避免地址随机变化。首先,升级cpolar至专业版及以上,然后在官网保留一个固定TCP地址。进入cpolar管理界面,编辑隧道信息,将保留的固定地址填入,更新隧道。最后,在IDEA中新建SSH连接,输入固定地址和端口,验证连接。成功后,即可稳定远程开发。
|
1月前
|
网络协议 Java Linux
如何在IDEA中使用固定公网地址SSH远程连接服务器开发环境(二)
在IDEA中通过Cpolar实现固定公网地址SSH远程连接到Linux服务器开发环境,主要步骤包括:1) 在Linux服务器上安装Cpolar,使用一键脚本进行安装和启动服务;2) 登录Cpolar Web UI,创建隧道,指定隧道名称、协议、本地地址(SSH默认端口22)、临时随机TCP端口和中国地区;3) 使用生成的公网TCP地址在IDEA中新建SSH连接,输入该地址和端口,完成远程连接。这种方式允许开发者在任何地方通过固定的公网地址进行远程开发,而无需公网IP。