Linux Shell常用小技巧
1.批量替换文件中匹配字符串
# sed不支持零宽断言,所以匹配@和<<之间的内容,不包括<<,可以用`@[^< ]*`
# 这个正则代表@和空格或者<之间,且不包含空格和<
sed -i 's/@[^<]*<<//g' /path/to/directory/*.sh
-i 表示在原始文件中直接修改,而不是输出到标准输出
s/ 表示替换操作的开始
@[^<]*<< 正则表达式,以@开头,零个或者多个非<字符,<<结尾
// 表示替换成空字符,也表示删除
g 表示全局替换,即文件中的每一处匹配字符串都会被替换
2.打印输出的某一列
df -k|awk '{print $5}'
打印第五列
3.grep不输出匹配结果
#!/bin/bash
# 如果不用-q,会把匹配行也打印出来
if cat test.sh|grep -q sqlplus;then
echo 'ok'
else
echo 'ng'
fi
#!/bin/bash
# name:IOErrorDisablePath.sh
# author:monkey
# date:20230602
# describe:When the path encounters an error, disable this path.
# The path to the monitored log file.
LOG_FILE="/var/adm/vx/dmpevents.log"
# The keyword being monitored.
KEYWORD="I/O error"
tail -F "$LOG_FILE" | while read -r line; do
if echo "$line" | grep -q "$KEYWORD"; then
ErrorPath=$(echo "$line" | grep -oP '(?<=Path )\w+(?=\()')
sleep 2
if vxdmpadm getsubpaths | grep -i "$ErrorPath" | grep -q "DISABLED"; then
echo "Path $ErrorPath is already disabled."
else
echo "Disabling path: $ErrorPath"
pwwn=$(vxdmpadm getportids path=$ErrorPath | tail -1 | awk '{print $4}')
vxdmpadm disable pwwn=$pwwn
fi
fi
done
4.root以oracle身份执行命令
主要有两种方式,一种是su -c,一种是su -l,其中su -l会进去到oracle用户的shell环境中(包括环境变量),常用于脚本中。su -c不会进去oracle用户的shell环境中,不过能包含环境白能量,常用于以oracle用户执行单个命令
4.1.su -c方式
# 在root下查看oracle数据库监听状态
su - oracle -c "lsnrctl status"
4.2.su -l方式
su -l oracle << eof
sqlplus -S / as sysdba << eofsp
show pdbs;
eofsp
eof
5.scp无需存储know_host
修改sshd的配置文件
vi /etc/ssh/ssh_config
#################################
#rictHostKeyChecking no
#UserKnownHostsFile /dev/null
#################################
6.保证同一时间只有一个shell脚本实例在运行
使用一个文件来表示是否有脚本实例在运行,如果文件存在,就说明有实例在运行
判断部分主要是防止进程执行完了但是文件未被清理(例如被kill -9),kill -0可以看看进程号对应的进程是否还在,后面的ps -fp可以保证进程号跑的进程就是这个脚本的实例
#!/bin/bash
# name: single_instance_script.sh
# author: monkey
# date: 20231114
# describe: Ensure that only one instance of this script is running at a time
SCRIPT_PATH=$(readlink -f "$0")
SCRIPT_NAME=$(basename "$SCRIPT_PATH")
LOCKFILE="$(dirname $SCRIPT_PATH)/.${SCRIPT_NAME}.lock"
# Check if lock file exists and another instance is running
if [ -e "$LOCKFILE" ] && kill -0 "$(cat "$LOCKFILE")" && ps -fp $(cat "$LOCKFILE") | grep -q "$SCRIPT_NAME"; then
echo "Another instance is already running. Exiting.--->$(date +"%Y-%m-%d %H:%M:%S")"
exit 1
fi
# Make sure the lockfile is removed when we exit and then claim it
trap "rm -f $LOCKFILE; exit" INT TERM EXIT
echo $$ > "$LOCKFILE"
# Place the main logic part of the script here
echo "Script is running..."
sleep 100
echo "Script completed."
7.获取shell脚本路径
#!/bin/bash
dir=$(dirname "$0")
echo "$dir"
dir=$(pwd)
echo "$dir"
dir=$(dirname $(realpath "$0"))
echo "$dir"
dir=$(dirname "${BASH_SOURCE[0]}")
echo "$dir"
dir=$(dirname "$(readlink -f "$0")")
echo "$dir"
在root用户的crontab下的输出:
脚本在/data/scripts/下,在/data下执行sh scripts/get_current_path.sh
命令,输出结果: