bash是shell的一种,shell是一种命令解释器

查看环境变量的命令:env、export
系统变量:

  • $PATH # PATH变量
  • $RANDOM # 系统变量

设置/修改环境变量:export xxx=xxx (写入/etc/profile 永久生效、写入~/.bash_profile,单用户生效
运行脚本:sh xxx.sh ( sh软连接到bash,本质还是bash

设置vim头部注释

  1. vim /etc/vimrc # 或者家目录下./vimrc
  2. set ignorecase
  3. autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"
  4. func SetTitle()
  5. if expand("%:e") == 'sh'
  6. call setline(1, "#!/bin/bash")
  7. call setline(2,"##############################################################")
  8. call setline(3, "# File Name:".expand("%"))
  9. call setline(4, "# Version:V1.0")
  10. call setline(5, "# Author:Rdymy")
  11. call setline(6, "# Organization: wifond")
  12. call setline(7, "# Desc:")
  13. call setline(8,"##############################################################")
  14. endif
  15. endfunc

开机执行脚本小项

  1. vim /server/scripts/shell/01_login_info.sh
  2. ########
  3. #1.赋值
  4. #########
  5. sys_hostname=`hostname`
  6. sys_ip_addrs=`hostname -I`
  7. sys_mem_total=`free -h |awk 'NR==2{print $2}'`
  8. sys_mem_free=`free -h |awk 'NR==2{print $NF}'`
  9. sys_load=`uptime |awk '{print $(NF-2),$(NF-1),$NF}'`
  10. #########
  11. #2.输出
  12. #########
  13. cat <<EOF
  14. 主机名: ${sys_hostname}
  15. ip地址: ${sys_ip_addrs}
  16. 总内存: ${sys_mem_total}
  17. 可用内存: ${sys_mem_free}
  18. 系统负载: ${sys_load}
  19. EOF
  20. ln -s /server/scripts/shell/01_login_info.sh /etc/profile.d/01_login_info.sh

基操

sh -x 测试脚本 set -x/+x # 指定测试行号 用双引号包裹,别用单引号 建议用${}取变量

脚本变量

$0、$1…. 取脚本名和后面的参数
$# 取参数的个数/字符串长度
$@ 取出所有参数
$* 取出所有参数、加上双引号就不能用for遍历了
$?
$$ 当前脚本的pid
$! 上一个后台命令的pid
其他方法(1.cat /var/run/xxx.pid # 只有主进程的pid
2.pidof 进程
$_ 上一个命令最后的参数

变量子串

p82

默认参数

${haha:=666}

内置关键字

命令 参数 案例
read -p/t/s
提示信息/超时时间/隐藏内容
read -s -t 3 -p "请输入2个数字:"
exit 退出脚本 返回值(0-255) exit 1
return 退出函数 返回值 用于函数

运算

awk: awk -vbianliang1=$1 -vbianliang2=$2 'BEGIN{print n1/n2}' # -v选项是awk和shell沟通的桥梁
bc -l : echo 2^10 |bc -l # 幂运算还是用**比较符合我的习惯
let a+b # 变量运算

条件表达式/判断/case

[[ xxx ]]

  • [[ -d xxx ]] # 判断是不是目录
  • -f # 判断是不是文件
  • -x # 判断是否是可执行文件
  • -s # 判断文件是否有内容
  • -n # 判断变量是否有内容
  • =~ 正则 # 判断内容是否和正则匹配
  • == 等于
  • 可以配合!使用,[[ ! $num =~ ^[0-9]+$ ]]
  • 大于等于/小于等于/不等于 -gt -lt -ne

  • -e # 可以判断一切

  • -L # 软连接

if 小项目

  1. #!/bin/bash
  2. # shift + del 删除整行
  3. # shift + alt 选中整列
  4. read -p "请输入用户名: " user
  5. #变量不能为空
  6. if [[ $user = "" ]];then
  7. echo "用户名不能为空"
  8. exit 2
  9. fi
  10. #判断用户是否存在
  11. id $user &>/dev/null
  12. if [ $? -ne 0 ];then
  13. echo "用户 $user 不存在"
  14. exit 1
  15. fi
  16. # 用户登录信息
  17. user_shell=`awk -F: -vname=$user '$1==name{print $NF}' /etc/passwd`
  18. if [ "$user_shell" = "/bin/bash" ];then
  19. if_login="可以登录"
  20. else
  21. if_login="无法登录"
  22. fi
  23. # 用户uid、家目录
  24. user_ids=`awk -F: -vname=$user '$1==name{print $3,$4}' /etc/passwd`
  25. user_homedir=`awk -F: -vname=$user '$1==name{print $6}' /etc/passwd`
  26. # find / -type f -user oldboy 2>/dev/null
  27. # 最后一次登录
  28. user_login_info=`lastlog |awk -vname=$user '$1==name{$1=""; print $0}'`
  29. #4.输出
  30. cat <<EOF
  31. 用户名: $user
  32. 是否可以登录: $if_login
  33. 用户UID,GID: $user_ids
  34. 用户家目录: $user_homedir
  35. 最近的登录情况: $user_login_info
  36. 用户的文件: \`\`
  37. EOF

case 小项目

  1. choice="$1"
  2. proc_cnt=`ps -ef|grep nginx|grep -v grep|wc -l`
  3. case $choice in
  4. start)
  5. [ $proc_cnt -eq 0 ] && \
  6. /app/sersync/bin/sersync -rdo /app/sersync/conf/www_confxml.xml &>/dev/null && echo "启动成功" || \
  7. echo "正在运行, 可以选择重启"
  8. ;;
  9. stop)
  10. [ $proc_cnt -ne 0] && \
  11. pkill sersync && echo "关闭成功" || \
  12. echo "没有可以关闭的进程"
  13. ;;
  14. restart)
  15. [ $proc_cnt -ne 0 ] && \
  16. pkillsersync && \
  17. /app/sersync/bin/sersync -rdo /app/sersync/conf/www_confxml.xml &>/dev/null && echo "重启成功" || \
  18. echo "没有可以重启的进程"
  19. ;;
  20. status)
  21. [ $proc_cnt -ne 0 ] && \
  22. ser_status="sersync is running" &&\
  23. ser_pid=`pidof sersync` && \
  24. echo "服务的状态: $ser_status, pid为: $ser_pid" || \
  25. ser_status="sersync is not running" && echo"服务的状态:$ser_status"
  26. ;;
  27. no|NO|n|N)
  28. echo "拜拜~" && exit 1
  29. ;;
  30. *)
  31. echo "输入错误正确的格式: sh $0 {start|stop|restart|status}"
  32. esac

函数 小项目

  • 函数中定义的变量不是局部的
  • 函数中的变量
    • $# 参数个数
    • $0 第一个参数
    • $* 所有参数 ```bash

      !/bin/bash

      加载库

      source /etc/init.d/functions

url=$1

port=$2

check_port(){ until [[ -n $url && -n $port ]]; do if [[ $url == q ]];then return fi read -p “输入q退出 输入网址和端口号,并以空格分隔 “ url port done

if [[ $port =~ ^[0-9]+$ && $port -le 65536 ]] ;then [[ $url =~ ^(https?://)?([a-zA-Z0-9]+.)?[a-zAZ0-9]+.[a-zA-Z]{1,5}$ || $url =~ ^(https?://)?[0-9]+[0-9.]+[0-9]+$ ]] || \ echo “网址无效” || return if nc -w 1 -z $url $port ;then action “$url 的端口$port 访问is “ /bin/true else action “$url 的端口$port 访问is “ /bin/false fi else action “端口无效” /bin/false fi }

check_port

测试本地端口则域名填写localhost

```bash
#!/bin/bash
# 加载库
source /etc/init.d/functions

# set -x
check_para() {
  url=
  port=
  until [[ -n $url && -n $port ]]; do
    read -p ":  " url port
    if [[ $url =~ ^[q|no|n|N|exit|quit|Q]$ ]]; then   
      return 1
    fi
    if [[ $url == get ]]; then   
      echo -e `curl -s ipconfig.io`
      return 1
    fi
    [[ -n $url && -n $port ]] || echo -e "\E[1;31m缺少端口\E[0m"
  done
  return 0
}

check_port() {
  flag=0

  while [[ $flag == 0 ]]; do
    check_para || return

    if [[ $port =~ ^[0-9]+$ && $port -le 65536 ]]; then
      [[ $url =~ ^(https?://)?([a-zA-Z0-9]+\.)?[a-zAZ0-9]+\.[a-zA-Z]{1,5}$ || $url =~ ^(https?://)?[0-9]+[0-9.]+[0-9]+$ || $url == localhost ]] || {
        echo -e "\E[1;31m网址格式错误\E[0m \n "
        continue
      }

      ping -c 1 -W 1 www.baidu.com &>/dev/null || {\
        echo "联网失败,检查网络配置或联系管理员"
        return
      }
      ping -c 1 -W 1 $url &>/dev/null || {\
        echo "网址解析失败,该网址可能不存在"
        continue
      }

      if nc -w 1 -z $url $port; then
        action "$url 的端口$port 访问is " /bin/true
      else
        action "$url 的端口$port 访问is " /bin/false
      fi
    else
      echo -e "\E[1;31m端口无效\E[0m \n "
    fi
  done
}

echo "
-----------------帮助手册-------------------
1. 输入网址和端口号,并以空格分隔
2. 没有网址则填写ip地址和端口号,并以空格分隔
3. 测试本机使用的端口则网址填写localhost或127.0.0.1
4. 获取本机公网IP输入 get
5. 退出请按q      或者/no/n/N/exit/quit/Q
"
check_port

for小项目

# for n in {1..6}
# for n in 1 2 3 4 5
# for n in $arr # 取的是内容,不是下标
# for n in `cat xxx.txt`

生成随机数的方法

# 1.
uuidgen
# 2. 
# -l 密码长度 -d 数字数量 -s special 特殊字符 -C 大写字母 -c 小写字母
mkpasswd  -l 10  -d 0 -s 0 -C 0
#3. 
# -c取反 -d删除
tr -cd 'a-z' </dev/urandom |head -c10
# 4.
# %N纳秒
date +%N |md5sum 

# 5.
# 0-32767
echo $RANDOM   
echo $((RANDOM+10000000)) |md5sum

while小项目

#!/bin/bash

i=0
let ran=$RANDOM%100

num_check(){
  [[ $guess =~ ^[0-9]+$ ]] || {echo "重新输入" && continue}
}

check(){
  if [[ i<=5 ]];then
    echo "猜了$i次,勇敢牛牛"
  else
    echo  "猜了$i次,ybb"
  fi
}

while true; do
  read -p "输入数字:    " guess
  num_check
  let i++
  if [[ $guess > $ran ]];then
    echo "大了"
  elif [[ $guess < $ran ]];then
    echo "小了"
  else
    check
    exit 1
  fi
done

#  while read line/xxx
#  do
#  done<xxx.txt

数组小项目(可以用cat读取文件

arr=(1a 2b 3c 4d)
# 输出数组中的所有值
echo ${arr[*]}
# 输出数组个数
echo ${#arr[*]}
# 数组的循环方式,i是值,不是索引
for i in ${arr[*]}
# 数组的赋值方式
arr=(`cat test1`)
echo ${arr[*]}

# 下标赋值,可以不创建空变量,直接赋值
arr=()
arr[1]=1