整理 google doc:Basics: Linux Basic

命令执行本质

一个命令行终端是一个shell进程,在这个终端里执行的程序都是作为该shell进程的子进程。 如果子进程命令阻塞终端shell进程,shell进程就会等待子进程退出才能接收其他命令; 如果关掉了shell终端,,依附的所有子进程都会退出; 加上&号可以避免这种情况,原理是将命令挂在systemd系统守护进程名下,其他办法还有nohup或者开tmux或者screen,并且加&可以让shell进程不再阻塞,从而继续响应新命令;

set -x 可以显示shell在执行什么程序

当使用 sudo 时,系统会使用 /etc/sudoers 这个文件中规定的该用户的权限和环境变量

重定向/管道

用户身份和权限

su – The difference between the su and the hyphenated su – commands is the su command without arguments keeps almost all environment variables belonging to the original user. Contrary to this, the hyphenated su – command clears most environment variables.

su _gvm
This account is currently not available.

sudo -u _gvm gvmd --migrate
sudo su -l _gvm -s /bin/bash

sudo sh -c "cmds"


Permissions take a different meaning for directories. Here’s what they mean:

系统启动用户

-----------------------------------------------------
--- mysql
-----------------------------------------------------
$ systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)                                                                                          
   Active: active (running) since Thu 2021-07-08 09:44:33 SGT; 2 months 1 days ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 2934 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)                                             
  Process: 2913 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 2936 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─2936 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

$ vim /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql

Type=forking

PIDFile=/var/run/mysqld/mysqld.pid
.....
# Start main service
ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS
...........

-----------------------------------------------------
--- keepalived
-----------------------------------------------------
$ systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2021-08-29 14:39:15 SGT; 1 weeks 2 days ago
  Process: 15401 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 15402 (keepalived)

$ vim /usr/lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=syslog.target network-online.target

[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

可以看到mysqld的实际用户是mysql,而keepalived没有指定,所以其用户就是执行启动命令systemctl start keepalived的用户

About Env

先确认默认的shell: BASH OR ZSH OR..

echo $0 or echo $SHELL or ps -p $$

改变默认shell

cat /etc/shells
type -a bash
chsh -s /usr/bin/bash
restart

env

The files in /etc directory sets the respective shell configuration for all the users on the system. This is normally set up by the system administrator.

The files in the home directory of the user are user-specific, obviously. This allows users to create alias for frequently used commands or use a custom PATH variable for a program.

i) 特定用户的PATH ~/bashrc ~/bash_profile

ii) system wide全局PATH /etc/profile或/root/.bashrc (/etc/environment?)

Anything in ~/.profile and ~/.bashrc is run after /etc/profile and /bash.bashrc

所以如果是修改了/etc/profile对root或sudo操作无效,要看下root下面的~/.bashXXX是不是有PATH设置,

如果还不生效,就要看下/etc/sudoers: Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin,可以使用 sudo -E 绕过

For some setups the -E switch will not work. To “workaround” it you can use sudo env "PATH=$PATH" bash. This will also carry your current $PATH forward to your sudo environment.

登录式 shell 和非登录式 shell

https://linuxhandbook.com/login-shell/

https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell

举例1:

echo $0
- `-bash` 中 `-` 表示当前是一个 login shell
- `bash` 表示不是 login shell

用户在当前交互式的shell中执行:
$ bash
就会开启一个新的 subshell,这个subshell就是一个 non-login shell,在该subshell中可以读取`~/.bashrc` 也可以读取`~/.bash_profile`(继承parent)

On desktop Linux, you don't use login shell. Your login is managed by a display manager. This is why when you open a terminal in Linux desktop, you'll see that even the first shell running in the terminal is not login shell. 

举例2:

https://www.tecmint.com/change-a-users-default-shell-in-linux/

There are several reasons for changing a user’s shell in Linux including the following:

  1. To block or disable normal user logins in Linux using a nologin shell.
  2. Use a shell wrapper script or program to login user commands before they are sent to a shell for execution. Here, you specify the shell wrapper as a user’s login shell.
  3. To meet a user’s demands (wants to use a specific shell), especially those with administrative rights

举例3 non-interactive, non-login shell:

使用crontab自动启动jar的时候,java代码中getHostName抛错,手动启动则没有问题

----------------------------------------------------------------------------------------------------------
--- java code
----------------------------------------------------------------------------------------------------------
private Long getDataCenterId(){
        int[] ints = StringUtils.toCodePoints(SystemUtils.getHostName());
        int sums = 0;
        for (int i: ints) {
            sums += i;
        }
        return (long)(sums % 32);
    }
    
Caused by: java.lang.NullPointerException
	at com.lyhistory.util.IdWorkerConfiguration.getDataCenterId(IdWorkerConfiguration.java:64)
	at com.lyhistory.util.IdWorkerConfiguration.getDateFromConfig(IdWorkerConfiguration.java:43)
	
查了下,在linux下面,SystemUtils.getHostName()实际是去获取linux env的HOSTNAME,
在该linux机器上使用执行crontab对应相同的用户登录,并执行env,正常显示HOSTNAME(当然了,毕竟手动运行没问题)
所以合理的怀疑是,crontab没有拿到env


----------------------------------------------------------------------------------------------------------
--- crontab
----------------------------------------------------------------------------------------------------------
$ crontab -e
44 17 * * * /opt/scripts/start_some_service.sh && &>> /opt/logs/start_some_service`date +\%F`.log   2>&1

----------------------------------------------------------------------------------------------------------
--- start_some_service.sh
----------------------------------------------------------------------------------------------------------
$ vim start_some_service
#!/bin/bash 

readonly PROGNAME=$(basename $0)
readonly PROGDIR=$(readlink -m $(dirname $0))

# source env
L_INVOCATION_DIR="$(pwd)"
L_CMD_DIR="/opt/scripts"

if [ "${L_INVOCATION_DIR}" != "${L_CMD_DIR}" ]; then
  pushd ${L_CMD_DIR} &> /dev/null
fi

source ./_set_env.sh
./start_service.sh A
./start_service.sh B

----------------------------------------------------------------------------------------------------------
--- start_service.sh
----------------------------------------------------------------------------------------------------------
$ vim start_service.sh
PID=`ps -aef | grep -v grep | grep "java -server -jar ./${1}.jar" | awk '{print $2}'`

if [ ! -z "$PID" ]; then
        echo "Service $1 already running on the server. PID is [$PID];"
        exit 0
fi

ulimit -c unlimited

nohup java -server -jar $1.jar > ../logs/`date +\%F`_$1_`date +\%H.%M.%S`.log 2>&1 &
sleep 1
PID=`ps -aef | grep -v grep | grep "java -server -jar ${1}.jar" | awk '{print $2}'`

if [ ! -z "$PID" ]; then
        echo "Service $1 started. PID is [$PID]"
else
        echo "Failed to start service $1"
fi

popd &>/dev/null


----------------------------------------------------------------------------------------------------------
--- 修复方式
----------------------------------------------------------------------------------------------------------
start_some_service.sh 替换 #!/bin/bash 为 #!/bin/bash -l
或者crontab添加bash -l
44 17 * * * bash -l /opt/scripts/start_some_service.sh && &>> /opt/logs/start_some_service`date +\%F`.log       2>&1
----------------------------------------------------------------------------------------------------------
--- 原因
----------------------------------------------------------------------------------------------------------
$ man 5 crontab
............
Several environment variables are set up automatically by the cron(8) daemon.  SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd line of  the  crontab´s
       owner.  HOME and SHELL can be overridden by settings in the crontab; LOGNAME can not.

       (Note: the LOGNAME variable is sometimes called USER on BSD systems and is also automatically set).
.............

$ man bash
 -l        Make bash act as if it had been invoked as a login shell (see INVOCATION below).

The -l option tells bash to read all the various "profile" scripts, from /etc and from your home directory. Bash normally only does this for interactive sessions (in which bash is run without any command line parameters).

Normal scripts have no business reading the profile; they're supposed to run in the environment they were given. That said, you might want to do this for personal scripts, maybe, if they're tightly bound to your environment and you plan to run them outside of a normal session.

A crontab is one example of running a script outside your session, so yes, go do it!

refer:
https://www.baeldung.com/linux/load-env-variables-in-cron-job
https://unix.stackexchange.com/questions/422499/what-are-the-pros-and-cons-in-using-the-l-in-a-script-shebang/422505
https://stackoverflow.com/questions/2229825/where-can-i-set-environment-variables-that-crontab-will-use
https://stackoverflow.com/questions/36885909/cronjob-does-not-execute-a-script-that-works-fine-standalone/69100347#69100347
https://unix.stackexchange.com/questions/321315/get-cron-to-run-in-the-same-environment-as-i-get-with-ssh-login

安装包管理

不同发行版选择

基本安装方法

常见问题:

apt

apt vs apt-get
更新repo:apt update
apt upgrade / apt full-upgrade
apt search "PKG"
apt list --installed | grep "PKG"

yum

更新repo:yum clean all / yum repolist / yum check-update 
yum provides package-name / rpm -q --provides openssl
yum list/search/info package-name
yum update package-name
yum history
yum history info 21

// find references
rpm -q --whatrequires openssl

[[email protected] ~]# yum repolist
Loaded plugins: fastestmirror, langpacks
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Determining fastest mirrors
 * base: mirror.newmediaexpress.com
 * epel: mirrors.aliyun.com
 * extras: mirror.newmediaexpress.com
 * updates: mirror.newmediaexpress.com
repo id                                                                                   repo name                                                                                                       status

!base/7/x86_64                                                                            CentOS-7 - Base                                                                                                 10,097

!docker-ce-stable/x86_64                                                                  Docker CE Stable - x86_64                                                                                           63

!epel/x86_64                                                                              Extra Packages for Enterprise Linux 7 - x86_64                                                                  13,499

!extras/7/x86_64                                                                          CentOS-7 - Extras                                                                                                  307

!ius/x86_64                                                                               IUS for Enterprise Linux 7 - x86_64                                                                                714

!updates/7/x86_64                                                                         CentOS-7 - Updates                                                                                                 997

repolist: 25,677


#yum repolist
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
repo id                                                                              repo name                                                                                                            status

nodesource/x86_64                                                                    Node.js Packages for Enterprise Linux 7 - x86_64                                                                         37

repolist: 55,117

DNF, or Dandified Yum, which is the next major version of the Yum package manager was introduced with Fedora 18. As of Fedora 22, it has become the default package manager.

https://www.rootusers.com/how-to-install-dnf-package-manager-in-centosrhel/

服务管理 service/systemctl

System V

is the oldest init system, used in Debian 6 and earlier Ubuntu 9.04 and earlier CentOS 5 and earlier In System V, an init script is a shell script. They are also called rc (run command) scripts. The scripts are located under the /etc/init.d directory

To make a service restart after a crash or reboot, you can usually add a line like this to the init script:
ms:2345:respawn:/bin/sh /usr/bin/service_name

To enable/disable a System V service to start at system boot time, run this command:
sudo chkconfig service_name on
sudo chkconfig service_name off
sudo service service_name status

update-rc.d - install and remove System-V style init script links
https://manpages.ubuntu.com/manpages/xenial/man8/update-rc.d.8.html
  https://askubuntu.com/questions/72127/when-you-run-update-rc-d-myscript-default-what-is-called-on-startup-shutdown#:~:text=If%20defaults%20is%20used%20then,overridden%20if%20there%20are%20dependencies.

Upstart

came after System V and was used in Ubuntu 9.10 to Ubuntu 14.10, including Ubuntu 14.04 CentOS 6

To keep things simple, Upstart is backward-compatible with System V. The /etc/init.d/rc script still runs to manage native System V services. Its main difference is the way it allows multiple events to be associated with a service. This event-based architecture allowed Upstart to be a flexible service manager. At startup, Upstart will run any System V init scripts normally. It will then look under the /etc/init directory and execute the shell commands in each service configuration file. The files have a naming style of service_name.conf

systemd

is the newest Linux service manager, used in Debian 7 and above Ubuntu 15.04 and above CentOS 7 and above

systemd is backward-compatible with System V commands and initialization scripts. That means any System V service will also run under systemd. The main difference between systemd and the other two init methods is that systemd is responsible for the initialization of service daemons and other types of resources like device operating system paths, mount points, sockets, etc. The naming style for a unit file is service_name.unit_type. So, you will see files like dbus.service, sshd.socket, or home.mount

main location:

/lib/systemd/system/
/etc/systemd/system
ls -l /etc/systemd/system/default.target
sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service
sudo systemctl show --property "Requires" multi-user.target | fmt -10
sudo systemctl show --property "Requires" basic.target | fmt -10
sudo systemctl show --property "Wants" basic.target | fmt -10

sudo vi /etc/systemd/system/multi-user.target.wants/xxx.service


How To Configure a Linux Service to Start Automatically After a Crash or Reboot https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-2-reference
sudo systemctl daemon-reload
sudo systemctl restart mysqld.service

example -openvpn on kali linux

因为某国直接使用openvpn有问题,所以要开启scramble模式,因此我卸载了kali默认的openvpn, 安装了scramble option

apt remove openvpn
then
make install the patched version

结果无法用service/systemctl启动openvpn

$service/systemctl start openvpn
failed to start .service unit is masked

Check that the unit file is a symlink to /dev/null:
$file /etc/systemd/system/openvpn.service

/lib/systemd/system/openvpn.service: symbolic link to /dev/null

删除无效link后重启:

$sudo rm /lib/systemd/system/openvpn.service
$sudo systemctl daemon-reload

$service/systemctl start openvpn 

忘记尝试 sudo systemctl unmask openvpn.service

但是这一次显示状态有点奇怪:

$service/systemctl status openvpn
State active (exited) 

means that systemd has successfully run the commands but that it does not know there is a daemon to monitor. https://unix.stackexchange.com/questions/241970/what-does-status-active-exited-mean-for-a-systemd-service

$which open
/usr/local/sbin/openvpn

$sudo find / -name "openvpn.service"
/run/systemd/generator.late/openvpn.service

$/etc/init.d/openvpn still point to:
/usr/sbin/openvpn

configuration file for /etc/init.d/openvpn: /etc/default/openvpn  

修改 /etc/init.d/openvpn指向 /usr/local/sbin/openvpn即可

install /etc/init.d/script https://askubuntu.com/questions/335242/how-to-install-an-init-d-script

基础服务

网络

Ubuntu

注意,对于Ubuntu 17.10 switched from ifupdown (which uses the /etc/network/interfaces file) to netplan,

所以新版本已经找不到 /etc/network/interfaces

netplan貌似只是个接口: https://netplan.io/examples/

具体的控制还是: NetworkManager 和 networkd, 其中desktop版本默认是 NetworkManager,而对于无UI的server版本只能用networkd https://askubuntu.com/questions/1031439/am-i-running-networkmanager-or-networkd

To configure netplan, save configuration files under /etc/netplan/ with a .yaml extension (e.g. /etc/netplan/config.yaml), then run sudo netplan apply. This command parses and applies the configuration to the system. Configuration written to disk under /etc/netplan/ will persist between reboots.

---------------------------------------------------------
对于NetworkManager:
---------------------------------------------------------
First any interfaces defined in /etc/network/interfaces are ignored by network-manager. (man 5 NetworkManager)
systemctl status network-manager

vim /etc/netplan/01-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager       

UI是使用NetworkManager,所以直接打开控制面板来设置静态IP和DNS即可
address 192.168.0.109
netmask 255.255.255.0
gateway 192.168.0.1
DNS: 8.8.8.8
设置完等一会即可    

---------------------------------------------------------
对于Networkd:
---------------------------------------------------------
systemd-networkd will only manage network addresses and routes for any link for which it finds a .network file with an appropriate [Match] section. (man 8 systemd-networkd).
systemctl status systemd-netword

vim /etc/netplan/01-network-manager-all.yaml
network:
    version: 2
    renderer: networkd
    ethernets:
        enp3s0:
            dhcp4: true

Debain based : Kali

--- for debain:
配置静态ip
/etc/network/interfaces:
#auto eth0
#iface eth0 inet dhcp
auto eth0
iface eth0 inet static
address 192.168.0.109
netmask 255.255.255.0
gateway 192.168.0.1

sudo ifdown eth0
sudo ifup eth0
or
sudo /etc/init.d/networking restart

如果还是无法上网(上面172.17.5.36是某ISP提供的,貌似虚拟机无法用):
/etc/resolv.conf
nameserver 8.8.8.8

sudo systemctl restart systemd-resolved.service

解决后看下当前路由情况:
route -n

#Verify new IP settings:
ip a s eth0
#Verify new routing settings:
ip r
#Verify DNS servers settings:
cat /etc/resolv.conf
#Verify the internet connectivity:
ping -c 4 google.com

[email protected]:/home/lyhistory# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.0.109/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever

[email protected]:/home/lyhistory# ip route
default via 192.168.0.1 dev eth0 onlink 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.109 

Centos

--- for centos
vim /etc/sysconfig/network-scripts/ifcfg-eth0
HWADDR=00:08:A2:0A:BA:B8
TYPE=Ethernet
#BOOTPROTO=dhcp
BOOTPROTO=none	
# Server IP #
IPADDR=192.168.0.110
# Subnet #
PREFIX=24
# Set default gateway IP #
GATEWAY=192.168.0.1
# Set dns servers #
DNS1=8.8.8.8
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
# Disable ipv6 #
IPV6INIT=no
NAME=eth0
# This is system specific and can be created using 'uuidgen eth0' command #
UUID=41171a6f-bce1-44de-8a6e-cf5e782f8bd6
DEVICE=eth0
ONBOOT=yes

systemctl restart network


Troubleshooting

error: Package Requires

[lyhistory/opt]#nginx -v
nginx version: nginx/1.12.1
[lyhistory/opt]#yum localinstall nginx-1.20.1-1.el7.ngx.x86_64.rpm 
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Examining nginx-1.20.1-1.el7.ngx.x86_64.rpm: 1:nginx-1.20.1-1.el7.ngx.x86_64
Marking nginx-1.20.1-1.el7.ngx.x86_64.rpm as an update to 1:nginx-1.12.1-1.el7.ngx.x86_64
Resolving Dependencies
--> Running transaction check
---> Package nginx.x86_64 1:1.12.1-1.el7.ngx will be updated
---> Package nginx.x86_64 1:1.20.1-1.el7.ngx will be an update
--> Processing Dependency: libcrypto.so.10(OPENSSL_1.0.2)(64bit) for package: 1:nginx-1.20.1-1.el7.ngx.x86_64
--> Finished Dependency Resolution
Error: Package: 1:nginx-1.20.1-1.el7.ngx.x86_64 (/nginx-1.20.1-1.el7.ngx.x86_64)
           Requires: libcrypto.so.10(OPENSSL_1.0.2)(64bit)
 You could try using --skip-broken to work around the problem
** Found 2 pre-existing rpmdb problem(s), 'yum check' output follows:
redhat-access-insights-1.0.6-0.el7.noarch has missing requires of libcgroup
redhat-access-insights-1.0.6-0.el7.noarch has missing requires of libcgroup-tools
[lyhistory/opt]#cat /etc/os-release 
NAME="Red Hat Enterprise Linux Server"
VERSION="7.2 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="7.2"
PRETTY_NAME="Red Hat Enterprise Linux Server 7.2 (Maipo)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.2:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.2
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.2"


[lyhistory/opt]#openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013

[lyhistory/opt]#rpm -q --provides openssl
openssl = 1:1.0.1e-42.el7_1.9
openssl(x86-64) = 1:1.0.1e-42.el7_1.9
[lyhistory/opt]#rpm -q --provides openssl-libs | grep libcrypto.so.10
libcrypto.so.10()(64bit)
libcrypto.so.10(OPENSSL_1.0.1)(64bit)
libcrypto.so.10(OPENSSL_1.0.1_EC)(64bit)
libcrypto.so.10(libcrypto.so.10)(64bit)


[lyhistory/opt]#yum localinstall openssl-libs-1.0.2k-19.el7.x86_64.rpm 
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Examining openssl-libs-1.0.2k-19.el7.x86_64.rpm: 1:openssl-libs-1.0.2k-19.el7.x86_64
Marking openssl-libs-1.0.2k-19.el7.x86_64.rpm as an update to 1:openssl-libs-1.0.1e-42.el7_1.9.x86_64
Resolving Dependencies
--> Running transaction check
---> Package openssl-libs.x86_64 1:1.0.1e-42.el7_1.9 will be updated
--> Processing Dependency: openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9 for package: 1:openssl-devel-1.0.1e-42.el7_1.9.x86_64
--> Processing Dependency: openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9 for package: 1:openssl-1.0.1e-42.el7_1.9.x86_64
---> Package openssl-libs.x86_64 1:1.0.2k-19.el7 will be an update
--> Finished Dependency Resolution
Error: Package: 1:openssl-1.0.1e-42.el7_1.9.x86_64 (@anaconda/7.2)
           Requires: openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9
           Removing: 1:openssl-libs-1.0.1e-42.el7_1.9.x86_64 (@anaconda/7.2)
               openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9
           Updated By: 1:openssl-libs-1.0.2k-19.el7.x86_64 (/openssl-libs-1.0.2k-19.el7.x86_64)
               openssl-libs(x86-64) = 1:1.0.2k-19.el7
Error: Package: 1:openssl-devel-1.0.1e-42.el7_1.9.x86_64 (@local-repo)
           Requires: openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9
           Removing: 1:openssl-libs-1.0.1e-42.el7_1.9.x86_64 (@anaconda/7.2)
               openssl-libs(x86-64) = 1:1.0.1e-42.el7_1.9
           Updated By: 1:openssl-libs-1.0.2k-19.el7.x86_64 (/openssl-libs-1.0.2k-19.el7.x86_64)
               openssl-libs(x86-64) = 1:1.0.2k-19.el7
 You could try using --skip-broken to work around the problem
** Found 2 pre-existing rpmdb problem(s), 'yum check' output follows:
redhat-access-insights-1.0.6-0.el7.noarch has missing requires of libcgroup
redhat-access-insights-1.0.6-0.el7.noarch has missing requires of libcgroup-tools

[lyhistory]#rpm -q --whatrequires openssl
nginx-1.12.1-1.el7.ngx.x86_64



尝试解决

[lyhistory]#yum remove openssl-libs.x86_64 / yum remove openssl-libs-1.0.1e-42.el7_1.9.x86_64
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Resolving Dependencies
--> Running transaction check
---> Package openssl-libs.x86_64 1:1.0.1e-42.el7_1.9 will be erased
....
--> Finished Dependency Resolution
Error: Trying to remove "systemd", which is protected
Error: Trying to remove "yum", which is protected

失败!

最终解决

cd /etc/yum.repos.d/
vi nginx.repo
  [nginx]
  name=nginx repo
  baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
  gpgcheck=0
  enabled=1
                 
yum clean all 
yum repolist 
yum update nginx 
rpm -qa | grep nginx 
nginx -v

未尝试的另一种方案:

yum swap -- remove openssl-libs-1.0.1e-42.el7_1.9.x86_64 -- install openssl-libs-1.0.2k-19.el7.x86_64.rpm