刨根问底之shell里的运行环境

 |   

在Ubuntu里,我们经常在终端中使用sudo来提权–以普通用户的身份去行使管理员的权限(前提是知道管理员用户的密码),这样减少了root用户的登录次数和管理时间,也提高了系统的安全性。不过有时候我们会直接用su切换到管理员进行一系列操作。本篇博文就是总结sudosu对bash运行环境的影响。明白了这点,你将明白在公司里怎样使用代理。

起因

今天在公司准备使用命令行sudo /opt/logstash/bin/plugin install logstash-output-webhdfs给logstash安装logstash-output-webhdfs插件,以实现将logstash收集的日志信息存储到Hadoop文件系统这一目的。但是却一直提示如下错误:

Unable to download data from https://rubygems.org/ - 连接被对端重置 (https://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz)
ERROR: Installation aborted, verification failed for logstash-output-webhdfs

这里公司上网环境是使用了代理。本人在~/.bashrc中添加了export http_proxy=xxxexport https_proxy=xxx。接下来按照网上的解决方法作了如下尝试,均已失败告终。

  1. 用Google搜索错误提示 Unable to download data from https://rubygems.org
  2. 手动安装插件logstash-output-webhdfs

必备知识

  1. Windows & Linux 环境变量设置
    在windows系统里面,经常会遇到 设置环境变量的问题,特别是安装完Java JDK之后。我们很少在黑漆漆的命令行窗口中执行命令set path=%path%;D:\jdk\bin,因为这样设置只会在这个命令窗口中能识别java命令在D:\jdk\bin目录里,重新打开一个命令窗口后将无法识别。也就是说该path只对执行那个命令的shell有效。还有两种方法是设置系统变量或用户变量。二者的区别就在于系统变量对所有用户有效,而用户变量只对当前用户有效。经试验,win8系统中二者都无需重启就可以起作用。同理,linux里面对环境变量的设置和windows是共通的。它也有三种方式

    • 终端中设置 执行命令PATH=$PATH':/home/hjy/program/jdk/bin',同样java命令只能在当前窗口中识别,重开一个窗口java命令将无效。
    • 设置用户变量 linux里面关于用户变量的设置是在两个文件中,一个是/etc/profile,另一个是~/.profile。
    • 设置系统变量 linux里面关于系统变量的设置是在/etc/environment文件中。
  2. bashrc VS profile
    我们知道bashrc和profile都是linux系统里面设置环境变量的地方,但是二者也是有区别的。

    • profile – 配置shell
      profile是配置的意思,是某个用户唯一用来设置环境变量的地方,但是用户可用的shell有多个,像bash,sh,zsh之类的,但像环境变量这种只需要在统一的一个地方初始化就可以了,而这就是profile。而Ubuntu中 /etc/profile将在用户第一次登录(可以是图形也可以是终端)时被执行,其只做两件事。
      1. 设置shell使用bash(主要执行/etc/bash.bashrc)
      2. 查看/etc/profile.d中是否有相应的环境变量要设置(该文件夹中每个sh文件都是针对某个应用设置的环境变量,这个叫 可插拔功能)。 而 ~/.profile也是在用户第一次登录时被执行,其也是做两件事。
      3. 设置shell使用bash(主要执行~/.bashrc)
      4. 设置路径包含用户私有的执行文件目录(如果存在)
    • bashrc – 配置bash
      bashrc看名字就知道,是专门用来给bash做初始化的。像初始化bash的设置,代码补全,别名,颜色等。同理,还会有shrc,zshrc这样的文件存在,只是bash太常用了。在Ubuntu系统中,每次打开bash, /etc/bash.bashrc就会被执行,进行如下设置。 0. ==非交互模式则不进行下面的操作==
      1. 窗口可调整
      2. 增强$PS1
      3. 设置xterm(注释掉了)
      4. 交互模式中开启命令补全(注释掉了)
      5. 在bash中使用sudo
      6. 安装command-not-found包后bash的变化 而 ~/.bashrc中设置的就比较多了,具体可以看文档注释。
  3. 四种不同的 shell模式

    • 登录模式
      进入登录模式的shell需要一个特定的用户名和密码,就像我们按Ctrl + Alt + F1进入tty1后输入用户名和密码后成功登录系统的情况。

      Tips:
      该模式下,shell会自动执行/etc/profile和~/.profile文件,但不会执行任何bashrc文件,但是在这两个profile里面会手动去执行bashrc文件. *.bashrc.

    • 非登录模式
      非登录模式是指不用登录直接进入shell,它需要在特定用户登录状态下才能进入。就像在终端下直接输入bashbash -c ‘CMD’

      Tips:
      该模式下,shell不会自动执行profile文件。

    • 交互模式
      在交互模式的shell中,标准输入,输出和错误都显示在终端上,此时变量$PS1一定会被设置。像以bashbash -i命令启动。

      Tips:
      该模式下(未login),shell会去执行/etc/bash.bashrc和~/.bashrc文件。

    • 非交互模式
      非交互模式就是指shell里面没有交互,像执行命令bash -c ‘CMD’,像运行shell脚本等。

      Tips:
      该模式下,shell不会执行任何bashrc文件。

  4. su VS sudo
    su和sudo虽然不是具有相似功能的命令,但是它们的目的大部分情况是为了获取root权限。

    • su命令是switch user的简写,是用来切换用户的。当不加任何参数时,它将切换到root用户。它需要你想切换到的用户的密码,在输入密码后,你将切换到那个用户的运行环境。
    • sudo命令是superuser do的简写,能够以root的权限取执行命令,但是它需要的是当前用户的密码,而不是像su需要的是想要切换到的用户的密码。这样需要执行一些需要root权限的命令时就不需要频繁输入root用户的密码,当然前提是当前用户的信息是存档在特殊的文件(/etc/sudoers)中。默认情况下,系统将记住当前用户的密码一段时间,以方便用户不用经常输入密码。

下面我们来讨论一下 sudo和su命令对运行环境的影响: * sudo * sudo su
bash将以一个交互非登录模式运行,所以只有两个bashrc文件将被执行。所以当用户切换成root后,我们还在当前的工作的目录,而非/root目录。 * sudo su -
bash将以登录模式运行的,此时/etc/profile,~/.profile将会被执行,隐形的/etc/bash.bashrc和~/.bashrc也将会被执行。此时,我们的当前目录是/root。 * sudo -i -i是–login的简写,所以和sudo su -一样的情况 * sudo /bin/bash bash将以非登录模式运行,上面四个文件将不会被执行。

问题关键

上面提供的

待解决的问题

  1. /etc/profile文件中首先判断是否存在变量$PS1。该变量是什么时候被创建的?

参考文献

  1. 如何设置或更改PATH系统变量
  2. 如何更换rubygem镜像的源
  3. 如何手动安装logstash插件logstash-output-elasticsearch-shield
  4. 可插拔认证模块
  5. 维基百科sudo
  6. shell的四种模式
  7. su和sudo对运行环境的影响
技术茶话会
< 前一篇 后一篇 >