一、远程执行shell ,杀死test.jar进程【ps、awk 、单引号,双引号】【杂谈】
疑惑
ssh 接单引号; awk接双引号,且$需要转义。
为什么awk里面的变量要单独转义,而ssh通过单引号括起来的变量并不需要转义
ssh 192.168.1.12 'test=$(ps -ef| awk "!/grep/&&/prometheus/{print \$2}")&& echo $test'
马龙帅解释:
ssh发送命令给对方机器执行的时候,自己会包一层引用
为什么echo $test,不需要转义,而test变量里的子shell,$2需要被转义?
答:ssh 192.168.1.12 'test=$(ps -ef | awk "!/grep/&&/prometheus/{print $2}")&& echo $test' 因为ssh后的是单引号,所以发到目标机器上执行时,目标机器上执行的相当于命令行原内容:test=$(ps -ef | awk "!/grep/&&/prometheus/{print $2}")&& echo $test,所以,首先就可以明确$test不需要转义然后对于命令替换部分,$(ps -ef | awk "!/grep/&&/prometheus/{print $2}"),命令替换内的引号是自己管理自己的,跟外部命令无关,所以命令替换内部执行的命令行就是它的原文:ps -ef | awk "!/grep/&&/prometheus/{print $2}"
ps -ef | awk "!/grep/&&/prometheus/{print $2}" 作为原文去执行时,识别也有问题,awk需要用到单引号。
答:你不能真的当原文去执行啊,因为交互式命令行下,感叹号后不接空格是当作历史命令来解析的。
只是说引号这部分是相当于没变动。你写进脚本,就是真的原文了
马:
我这个图片里,因为ssh后是单引号,所以目标机器上执行的就是原文echo 1 2 | awk "{print $2}"和echo 1 2 | awk "{print \$2}",awk使用双引号,所以如果不对$2转义,$2就会替换为shell变量,也就是空,等价于{print},转义后,shell就把$符号留给awk了
简单来说,你可以把ssh ADDR 'CMD'当作 sh -c 'CMD'来理解,只不过是在目标机器上执行sh -c 'CMD
###
如果我想把awk的双引号变成单引号,这样就不需要转义$2了,但会和ssh的单引号冲突报错,有木有解决方案。
答:没办法,只能双引号然后在需要转义的地方转义,但如果目标机器上的sh是bash的软连接,还有方法。
我试了下zsh dash bash都支持$''
$''内部可以对单引号进行转义
其他处理思路
1、shell方法,pgrep去jar的PID
2、ansible方法
3、shell方法,不过执行的是远端的启动jar脚本,停止jar脚本
二、ssh执行shell,远程后找不到远程目录的问题。
处理方法:
versions=$(ssh root@${host} "ls -l ${code_deploy_backupdir}" | sed '1d' | awk -F " " '{print $9}' | awk -F "." '{print $3}')
三、docker镜像加速(2023年6月)
最近阿里云docker加速器出了些问题,docker.io容易超时 整理了一些可用的加速/代理地址:
比如
registry-mirrors": ["https://dockerhub.azk8s.cn","https://hub-mirror.c.163.com"]
还有 https://dockerproxy.com
https://docker.nju.edu.cn
https://docker.mirrors.sjtug.sjtu.edu.cn
四、安装Telnet服务,避免升级OpenSSH导致服务器不可连接。需要先下载安装Telnet组件。升级期间使用Telnet作为升级期间的服务器连接方式。
# 安装Telnet服务,避免升级OpenSSH导致服务器不可连接。需要先下载安装Telnet组件。升级期间使用Telnet作为升级期间的服务器连接方式。
Start_telnet() {
# 安装telnet
yum install -y xinetd telnet-server telnet &> /dev/null
# 创建普通用户,telnet默认不允许root登录
useradd tempuser
# 配置密码 根据实际情况设置
echo "123456" | passwd --stdin tempuser
# 备份sudoers文件
cp -rf /etc/sudoers ${file_backup}/sudoers_bak${date_time} &> /dev/null
# 配置tempuser用户授予sudo权限
echo "tempuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# 备份文件securetty
cp -af /etc/securetty ${file_backup}/securetty_bak${date_time} &> /dev/null
# 配置telnet登录的终端类型,增加一些pts终端
pts=$'pts/0\npts/1\npts/2\npts/3\npts/4' && echo "$pts" >> /etc/securetty
# 启动telnet服务
echo -e "\033[33m 正在启动telnet服务... \033[0m"
service xinetd start
systemctl enable telnet.socket
systemctl start telnet.socket
# 判断服务是否启动成功
if [ $? -eq 0 ]; then
echo -e "telnet服务启动成功。" "\033[32m 成功\033[0m"
else
echo -e "telnet服务启动失败。退出脚本..." "\033[31m 错误\033[0m"
exit
fi
}
防火墙设置(可选)
# 关闭或配置防火墙放通telnet服务23端口
Start_iptables() {
# 备份 iptables 配置
# iptables-save > /etc/sysconfig/iptables${date_time}
# 关闭防火墙
systemctl stop firewalld.service && systemctl disable firewalld.service
systemctl stop iptables.server && systemctl disable iptables.server
# 或者开放23端口
firewall防火墙状态放行telent服务23端口
firewall-cmd --permanent --add-port=23/tcp --zone=public
firewall-cmd --reload
# 或
iptables防火墙状态放行telent
iptables -A INPUT -p tcp --dport 23 -j ACCEPT
}
五、npm run build:prod打包失败的处理方法 (nodejs)
npm install --registry=https://registry.npmmirror.com
npm run build:prod
但报错:
1、 报错信息:
看npm ERR日志
2、 目录-项目文件:
3 报错日志:
9 verbose lifecycle ruoyi@3.6.0~build:prod: CWD:/root/RuoYi-Cloud/ruoyi-ui
10 silly lifecycle ruoyi@3.6.0~build:prod: Args: [ '-c ','vue-cli-service build'
11 silly lifecycle ruoyi@3.6.0~build:prod: Returned: code: 1 signal: null
12 info lifecycle ruoyi@3.6.0~build:prod: Failed to exec build:prod script
13 verbose stack Error: ruoyi@3.6.0 build:prod: 'vue-cli-service build
13 verbose stack Exit status 1
处理方法:
#(1)第一步
npm cache clean --force
#(2)第二步 删除node_modules文件夹
rm -rf node_modules
#(3)如果有package-lock.json文件就删除它,没有不用管,直接跳到第(4)步
rm -rf package-lock.json
#(4)安装模块
npm install
参考:https://blog.csdn.net/feifeia007/article/details/117477683
六、 k8s的ingress的rewrite需求随记
#需求:
想根据api去匹配 但是想访问到的是域名/login
#参考1:
path: /api(/|$)(.*) annotations: nginx.ingress.kubernetes.io/rewrite-target: /login/$2
### 解释↓
这个规则适用于在Kubernetes中使用Nginx Ingress控制器作为反向代理,并对请求路径进行重写。
该规则使用正则表达式匹配请求路径,并使用 nginx.ingress.kubernetes.io/rewrite-target 注解将请求的目标路径重写为 /login/$2。
具体来说:
path: /api(/|$)(.*):表示当请求路径以 /api 开头时,将会触发这个规则。
annotations: nginx.ingress.kubernetes.io/rewrite-target: /login/$2:表示将匹配到的请求路径重写为 /login/$2,其中 $2 表示正则表达式中的第二个捕获组的值。
例如,如果收到的请求路径为 /api/user/profile,根据这个规则,将会将请求的目标路径重写为 /login/user/profile。这样,请求将被转发到 /login 路径下的后端服务进行处理。
这个规则适用于需要在路径级别进行请求转发和重写的场景,例如将特定的API路径重定向到不同的后端服务。
参考2:
七、欧拉系统升级openssl至1.1.1.u,处理升级后无法使用yum和curl
#环境信息:
操作系统:BigCloud Enterprise Linux For Euler 21.10 LTS
升级之前openssl版本:OpenSSL 1.1.1f 31 Mar 2020
目标版本:openssl-1.1.1u.tar.gz
7.1 升级操作:
#!/bin/bash
cd /tmp/openssl-1.1.1u
./config --prefix=/usr/local/openssl shared enable-ssl3 enable-ssl3-method && make -j32 && make install
mv /usr/bin/openssl /usr/bin/openssl.bak
ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
ldconfig -v
echo 'export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH' >> /etc/profile
source /etc/profile
openssl version
7.2 报错信息:
#yum报错
]# yum install nginx -y
Traceback (most recent call last):
File "/usr/lib64/python3.7/site-packages/libdnf/error.py", line 14, in swig_import_helper
return importlib.import_module(mname)
File "/usr/lib64/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 670, in _load_unlocked
File "<frozen importlib._bootstrap>", line 583, in module_from_spec
File "<frozen importlib._bootstrap_external>", line 1043, in create_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
ImportError: /lib64/libcurl.so.4: symbol SSLv3_client_method version OPENSSL_1_1_0 not defined in file libssl.so.1.1 with link time reference
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/yum", line 57, in <module>
from dnf.cli import main
File "/usr/lib/python3.7/site-packages/dnf/__init__.py", line 30, in <module>
import dnf.base
File "/usr/lib/python3.7/site-packages/dnf/base.py", line 29, in <module>
import libdnf.transaction
File "/usr/lib64/python3.7/site-packages/libdnf/__init__.py", line 8, in <module>
from . import error
File "/usr/lib64/python3.7/site-packages/libdnf/error.py", line 17, in <module>
_error = swig_import_helper()
File "/usr/lib64/python3.7/site-packages/libdnf/error.py", line 16, in swig_import_helper
return importlib.import_module('_error')
File "/usr/lib64/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
ModuleNotFoundError: No module named '_error'
和
#curl报错
]# curl localhost
curl: relocation error: /lib64/libcurl.so.4: symbol SSLv3_client_method version OPENSSL_1_1_0 not defined in file libssl.so.1.1 with link time reference
7.3 报错信息:处理方法:
#加入/etc/profile
export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH
参考博客:https://blog.51cto.com/u_15642578/6670981 《华为超算平台git、cmake、wget、curl报错:SSLv3_client_method version OPENSSL_1_1_0 not define》
和
https://bbs.huaweicloud.com/blogs/298408 《yum 使用报错(ModuleNotFoundError: No module named '_error')解决方案》
八、shell 单双引号, ssh -t伪终端出现问题随记
8.1 普通用户批量复制/etc/shadow文件
root用户的情况
spawn scp $USER@$IP:/etc/shadow /tmp/shadowFile/shadow-$IP
普通用户的情况(有sudo权限)
]# cat receiveShadowFile.sh
#!/bin/bash
COMMAND=$*
HOST_INFO=host-test.info
#HOST_INFO=host-50-runScript.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
echo -e "----- $IP start--------------\n"
expect -c "
spawn ssh -t $USER@$IP \"sudo scp /etc/shadow test@192.168.1.100:/tmp/shadowFile/shadow-$IP\"
expect {
\"(yes/no\" {send \"yes\r\"; exp_continue}
\"password:\" {send \"$PASS\r\"; exp_continue}
\"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
}
"
echo -e "-----------end--------\n"
done
注意的坑
#注意需要加-t参数(伪终端),否则无法实现效果
spawn ssh -t $USER@$IP \"sudo scp /etc/shadow test@192.168.1.100:/tmp/shadowFile/shadow-$IP\"
#由于root被 permitRootLogin no .此时 root的ssh、 scp都是"失效"的。
普通用户nwom ,是可以 ssh test@192.168.1.100 ,然后sudo scp /etc/shadow xxx的
#手动执行的方法 (不推荐)
sudo scp /etc/shadow test@192.168.1.100:/tmp/shadowFile/shadow-$(hostname -I | grep -oE '192\.168\.[0-9]+\.[0-9]+' | head -1)\r
8.2 基线修复前提,批量生成xml文件
#脚本需求:
echo "Usage: sh 86c221be-6ab2-ef53-1589-fe16877914f4.sh <IP> <SU用户(SU或高权限用户)> <SU密码>";
#对应脚本:
]# cat createXml.sh
#!/bin/bash
COMMAND=$*
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
echo -e "-----start $IP --------------\n"
expect -c "
spawn ssh $USER@$IP \"cd /tmp/linux-config && sh 86c221be-6ab2-ef53-1589-fe16877914f4.sh $IP $USER $PASS\"
expect {
\"(yes/no)\" {send \"yes\r\"; exp_continue}
\"password:\" {send \"$PASS\r\"; exp_continue}
\"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
}
"
echo -e "------end-------------\n"
done
注意的坑:
#这里的双引号要加转义,否则报错。
spawn ssh $USER@$IP \"cd /tmp/linux-config && sh 86c221be-6ab2-ef53-1589-fe16877914f4.sh $IP $USER $PASS\"
#或者不加双引号,也能正常执行。 如:
spawn ssh $USER@$IP cd /tmp/linux-config && sh 86c221be-6ab2-ef53-1589-fe16877914f4.sh $IP $USER $PASS
#这里的 单引号 、双引号、可回顾以前写的单双引号知识点。
单引号、双引号、转义$ ( 意思是 \$(hostname -I) ) 、十六进制代替单双引号。
九、 ssh的-n参数 与 while循环 杂谈
-n只是禁止ssh读取标准输入里的数据.
如果while是while read line的话,while里使用ssh,应该加上-n,否则执行到ssh后会把while剩下想要读的所有行都给抢读了.
参考:https://blog.csdn.net/notsea/article/details/42028359 《ssh命令输入问题(-n选项作用)》
十、发现通过k8s创建的容器,在node节点上用inspect查看没有IP,在k8s matser节点上describe上能看到容器IP (杂谈)
describe:
看pause容器的网络
#docker network inspect <网络id>
docker network inspect 2052bfa7b244fe0c0596aea57be6d2e918126206d07e24eb14f6f340a27cdd63
我看了下containerd,是可以看到IP的,
[root@node03 ~]# nerdctl inspect fb791cfbd6f9 --namespace="k8s.io" |grep -i ip
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "192.168.3.102",
"IPPrefixLen": 24,
"IPAddress": "192.168.3.102",
"IPPrefixLen": 24,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/7d6731e523684b22a0f152ffb3bd6ee9.png)
```shell
docker inspect只看当前容器的网络名称空间,你共享的是pause网络名称空间看不到。你看pause它又是上层CNI提供的,这就看不到了。
containerd能看到,是他将容器的网络状态视为运行时的组成部分,所以nerctl inspect容器的信息,containerd 就能展示网络 对应的IP 。
```