如何解决 su 命令导致的环境变量丢失问题?

新手上路,请多包涵

现在在编写一个脚本,希望在root用户下收集oracle用户下的一些信息,但是发现在脚本中切换用户执行命令会出现环境变量问题。


[root@oracle01 ~]# su - oracle -c "$ORACLE_HOME/OPatch/opatch lsinventory"
-bash: /OPatch/opatch: No such file or directory
[root@oracle01 ~]# su - oracle -c "echo $ORACLE_HOME"

[root@oracle01 ~]# 

如上面的命令所示,ORACLE_HOME是个空。
oracle用户下确实设置了环境变量,但是使用su - oracle -c "echo $ORACLE_HOME"这种样子查看时却显示该变量为空。

要如何才能在切换oracle用户后正确使用$ORACLE_HOME变量呢?


[root@oracle01 ~]# su - oracle
Last login: Wed Mar 13 16:20:05 CST 2024 on pts/0
[oracle@oracle01 ~]$ cat ~/.bash_profile 
...省略一些输出
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1
...省略一些输出
[oracle@oracle01 ~]$ echo $ORACLE_HOME
/u01/app/oracle/product/11.2.0/db_1
[oracle@oracle01 ~]$ exit
logout
[root@oracle01 ~]# 
[root@oracle01 ~]# su - oracle -c "env|grep ORACLE_HOME"
ORACLE_HOME=/01/app/oracle/product/11.2.0/db_1
[root@oracle01 ~]# su - oracle -c "echo $ORACLE_HOME"

[root@oracle01 ~]# 
阅读 1.4k
avatarAI BotBETA

在Linux中,环境变量通常是在用户的shell会话中设置的。当你使用su命令切换用户时,新的shell会话会被启动,并且会读取该用户的配置文件(如.bash_profile.bashrc)来设置环境变量。然而,当你使用su - oracle -c "command"的形式时,command是在一个非交互式的shell中执行的,这意味着它不会读取用户的配置文件,因此环境变量也不会被设置。

要解决这个问题,你可以使用以下方法之一:

  1. 在命令行中直接设置环境变量
    su命令中直接设置所需的环境变量。例如:
su - oracle -c "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1; $ORACLE_HOME/OPatch/opatch lsinventory"
  1. 使用-s选项
    使用su命令的-s选项来启动一个新的shell,并读取用户的配置文件。例如:
su -s /bin/bash oracle -c "echo $ORACLE_HOME"

这里,/bin/bash是oracle用户的默认shell。使用-s选项将确保shell会读取用户的配置文件并设置环境变量。

  1. 使用source或.命令
    su命令中,你可以使用source.命令来在当前shell中读取用户的配置文件。例如:
su - oracle -c "source ~/.bash_profile; echo $ORACLE_HOME"

或者

su - oracle -c ". ~/.bash_profile; echo $ORACLE_HOME"

选择适合你需求的方法,并确保在脚本中使用正确的方式来设置环境变量。

1 个回答

su - oracle -c "echo $ORACLE_HOME"

用双引号("echo $ORACLE_HOME")的话,环境变量会在 su 执行之前被替换,所以它被替换成了当前用户的 ORACLE_HOME 。

换成单引号 'echo $ORACLE_HOME' 试一下。