2022-03-23 14:24:01 +08:00

236 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Shell 笔记"
date: 2019-10-30T11:29:31+08:00
lastmod: 2019-10-30T11:29:31+08:00
tags: ["shell"]
categories: ["shell"]
---
## BASH 脚本的 $ 参数
- $$ #shell 本身 PID
- $! #shell 最后执行的后台PID
- $? #shell 结束代码
- $\* #参数列表 "$1 $2 ... $n"
- $@ #参数列表 "$1" "$2" ... "$n"
- $# #参数个数
- $0 #shell 脚本名
- $1...$n #shell 位置参数
## BASH 字符串处理
```bash
# 字符串 str 长度
${#str}
expr length "$str"
# 子串 substr 出现位置,找不到返回 0
expr index "$str" "$substr"
# 子串 substr 开头匹配,找不到返回 0
expr match "$str" "$substr"
# 字符串 str 抽取左起位置 pos 后 长度 len 的子串
${str:$pos}
${str:$pos:$len}
expr substr "$str" $pos $len
# 字符串 str 抽取右起位置 pos 前的子串
${str: -pos}
${str:(pos)}
# 正则 pat 抽取字符串 str 开头子串
expr match "$str" "\($pat\)"
expr "$str" : "\($pat\)"
# 正则 pat 抽取字符串 str 结尾子串
expr match "$str" ".*\($pat\)"
expr "$str" : ".*\($pat\)"
# 删除字符串 str 开头的最短子串 sub
${str#$sub}
# 删除字符串 str 开头的最长子串 sub
${str##$sub}
# 删除字符串 str 结尾的最短子串 sub
${str%$sub}
# 删除字符串 str 结尾的最长子串 sub
${str%%$sub}
# 替换字符串 str 第一个子串 sub 为字符串 rep
${str/"$sub"/"$rep"}
# 替换字符串 str 所有子串 sub 为字符串 rep
${str//"$sub"/"$rep"}
# 替换字符串 str 开头的子串 sub 为字符串 rep
${str/#"$sub"/"$rep"}
# 替换字符串 str 结尾的子串 sub 为字符串 rep
${str/%"$sub"/"$rep"}
# var为空或没有设置代入word否则代入var值
${var:-word}
# 如果var已经被设置且不为空则代入它的值否则代入word并且在后面var始终为word的值。位置参量不能用这种方式赋值。
${variable:=word}
# 如果变量var已被设置且值为非空代入word值否则什么也不代入
${variable:+word}
# 如果变量var已被设置值且为非空就代入它的值否则输出word并从shell中退出如果有省略了word,就会显示信息parameter null or not set.
${var:?word}
```
## BASH 数组
```bash
# 定义数组,有三种方式
declare -a array
array=()
array[0]='value0'
# 打印数组第一个元素
echo ${array[0]}
# 打印数组所有元素,有两种方式
echo ${array[@]}
echo ${array[*]}
# 打印数组所有索引,有两种方式
echo ${!array[@]}
echo ${!array[*]}
# 打印数组的元素个数,有两种方式
echo ${#array[@]}
echo ${#array[*]}
# 移除数组中索引为2的元素
unset array[2]
# 添加id为3的元素
array[3]=""
```
## BASH 字典
```bash
# 定义字典
declare -A dict
# 新增或修改键 k1 的值
dict['k1']='v1'
# 打印对应键的值
echo $['k1']
# 打印字典所有元素,有两种方式
echo ${dict[@]}
echo ${dict[*]}
# 打印字典所有键,有两种方式
echo ${!dict[@]}
echo ${!dict[*]}
# 打印字典的元素个数,有两种方式
echo ${#dict[@]}
echo ${#dict[*]}
# 移除键 k1
unset dict['k1']
```
## 终端环境变量 PS1 参数
- \d 日期格式为weekday month date例如"Mon Aug 1"
- \H 完整的主机名称
- \h 仅取主机的第一个名字
- \t 显示时间为24小时格式如 HH:MM:SS
- \T 显示时间为12小时格式
- \A 显示时间为24小时格式 HH:MM
- \u 当前用户的账号名称
- \v BASH的版本信息
- \w 完整的工作目录名称
- \W 利用basename取得工作目录名称所以只会列出最后一个目录
- \# 下达的第几个命令
- \$ 提示字符root 下提示符是 #,普通用户是 $
- \\[\e[i;j;km\\] \\[\e[0m\\] 建议PS1使用这种颜色控制字符
## 终端颜色 \033[F;Bm 控制编码
- F30 B40 黑色
- F31 B41 红色
- F32 B42 绿色
- F33 B43 黄色
- F34 B44 蓝色
- F35 B45 紫红色
- F36 B46 青蓝色
- F37 B47 白色
## 终端光标位置
- \033[K 清除从光标到行尾的内容
- \033[s 保存光标位置
- \033[u 恢复光标位置
- \033[0m 关闭所有属性
- \033[1m 设置高亮度
- \033[4m 下划线
- \033[5m 闪烁
- \033[7m 反显
- \033[8m 消隐
- \033[nA 光标上移n行
- \033[nB 光标下移n行
- \033[nC 光标右移n行
- \033[nD 光标左移n行
- \033[2J 清屏
- \033[?25l 隐藏光标
- \033[?25h 显示光标
- \033[y;xH 设置光标位置
## 解析迅雷链接
- echo 迅雷专用地址(去掉头 thunder://)|base64 -d
- 去掉头部 AA 和尾部 ZZ
## expect 自动输入密码
```bash
expect<<END
spawn ssh $DEST_HOST "REMOTE_COMMAND"
expect {
"*yes/no*" { send "yes\r"; exp_continue }
"*assword*" { send "password\r" }
}
expect eof
END
```
## 普通用户(username)免密 sudo
```bash
echo "username ALL = (root) NOPASSWD:ALL" >> /etc/sudoers
# 或
echo "cephdeploy ALL = (root) NOPASSWD:ALL" > /etc/sudoers.d/username
chmod 0400 /etc/sudoers.d/username
```
## 用户登陆操作记录
- 创建日志共存目录
```bash
mkdir /var/log/user_history -p
chmod 0777 /var/log/user_history -R
```
- 配置 history 历史文件 /etc/profile.d/history.sh
```bash
#!/bin/bash
export HISTSIZE=10000
export HISTTIMEFORMAT="[%F %T] "
LOG_DIR=/var/log/user_history
mkdir -p $LOG_DIR/$USER
if [ 0 -eq $? ]; then
SRC_IP="$(who -u am i 2>/dev/null | awk '{print $NF}' | sed 's/[()]//g')"
[ -z "$SRC_IP" ] && SRC_IP='127.0.0.1'
hist_file="$USER/${SRC_IP}_$(date +%Y%m%d-%H%M%S)"
export HISTFILE="$LOG_DIR/$hist_file"
else
echo "本次登陆没有监管10秒后自动断开!"
export TMOUT=10
fi
```