总结脚本高级命令trap, install, mktemp, expect、总结索引数组、求10个随机数的最大值与最小值、 使用递归调用,完成阶乘算法实现、解析进程和线程的区别?、 解析进程的结构。

一、 总结脚本高级命令trap, install, mktemp, expect, 进程优先级命令:nice, renice, 进程管理工具: ps, pstree, prtstat, pgrep, pidof, uptime,mpstat,top,htop, free, pmap, vmstat, iostat, iotop, iftop, nload, nethogs, iptraf-ng, dstat, glances, cockpit, kill, job, 任务相关的命令: at, crontab, 命令,选项,示例。

1、脚本高级命令trap, install, mktemp, expect

信号捕捉trap

#常见trap信号
[root@Rocky8 ~]#trap -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

# 系统发出指令信号时,将执行自定义指令,不执行原操作
trap '触发指令' 信号
 
# 忽略信号操作
trap '' 信号
 
# 恢复原信号操作
trap '-' 信号
 
# 列出自定义信号
trap -p

#当脚本正常或异常退出时,执行finish函数
#!/bin/bash
# **********************************************************
# * Author        : DingBaoHang
# * Email         : m15269032515@163.com
# * Create time   : 2023-05-16 10:47
# * Filename      : trap_exit.sh
# * Description   :
# **********************************************************
finish() {
echo finish |tee -a /root/finish.log
}

trap finish-$(date`%F %T`) exit

while true ;do
    echo running
    sleep 5
done
#查看结果
[root@Rocky8 ~]#cat /root/finish.log
finish-Tue May 16 11:00:19 CST 2023
finish-Tue May 16 11:00:23 CST 2023

mktemp创建临时文件

#常用命令
mktemp 
	-p //创建临时目录
	-d DIR //指明临时文件存放路径
#创建目录
[root@Rocky8 ~]#mktemp textXXX
textHDE
[root@Rocky8 ~]# ll
drwxr-xr-x. 2 root   root     4096 May 16 02:10 script
#创建文件
[root@Rocky8 ~]#mktemp httpdXXX.log
httpdVzr.log

install相当于mkdir、cp、修改文件属性

# 拷贝
[root@Rocky8 ~]#install a.txt /opt/
[root@Rocky8 ~]#ls /opt/
a.txt

# 只创建目录
install -d 
 
# 修改权限
install -m 600
 
# 修改所属主own
install -o 
 
# 修改所属组
install -g

expect

#利用expect实现非交互式远程关闭服务
[root@Rocky8 script]#cat expect3.sh
#!/bin/bash
# **********************************************************
# * Author        : DingBaoHang
# * Email         : m15269032515@163.com
# * Create time   : 2023-05-12 22:19
# * Filename      : expect3.sh
# * Description   :
# **********************************************************
NET=192.168.188
user=root
password=123456
IPLIST="
70
71
100
"
for ID in $IPLIST ;do
    ip=$NET.$ID
expect <<EOF
set timeout 20
spawn ssh $user@$ip
expect {
    "yes/no" { send "yes\n";exp_continue }
    "password" { send "$password\n"}
}
expect "#" { send "sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config\n" }
expect "#" { send "setenforce 0\n"}
expect "#" { send "exit\n"}
expect eof
EOF
done

2、进程优先级命令nice, renice

nice、renice

#nice命令
以指定的优先级来运行进程
#renice命令
可以调整正在执行中的进程的优先级
#实例ping 192.168.188.100
[root@Rocky8 script]#ping 192.168.188.100
PING 192.168.188.100 (192.168.188.100) 56(84) bytes of data.
64 bytes from 192.168.188.100: icmp_seq=1 ttl=64 time=1.47 ms
64 bytes from 192.168.188.100: icmp_seq=2 ttl=64 time=0.251 ms

[root@Rocky8 ~]#ps -aux |grep ping
root       46074  0.0  0.1 242284  2416 pts/1    S+   11:35   0:00 ping 192.168.188.100

3、进程管理工具

ps, pstree, prtstat, pgrep, pidof,uptime,mpstat,top,htop, free, pmap, vmstat, iostat, iotop, iftop, nload, nethogs, iptraf-ng, dstat, glances, cockpit, kill, job

# 进程信息(ps)
# 以内存的利用率来倒序排序
[root@Rocky8 ~]# ps axo pid,cmd,%cpu,%mem --sort -%mem
    PID CMD                         %CPU %MEM
    939 /usr/lib/snapd/snapd         0.0  1.0
    571 /sbin/multipathd -d -s       0.0  0.6
   1008 /usr/bin/python3 /usr/share  0.0  0.5
    932 /usr/bin/python3 /usr/bin/n  0.0  0.4
    946 /usr/libexec/udisks2/udisks  0.0  0.3
    528 /lib/systemd/systemd-journa  0.0  0.3
    913 /lib/systemd/systemd-resolv  0.0  0.3
    818 /usr/bin/VGAuthService       0.0  0.2
      1 /sbin/init                   0.0  0.2
    990 /usr/sbin/ModemManager       0.0  0.2
   1479 sshd: root@pts/0             0.4  0.2
  13711 sshd: root@pts/1             0.0  0.2
   1429 /lib/systemd/systemd --user  0.0  0.2
# 能够显示进程的父子关系
[root@Rocky8 ~]# ps auxf
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           2  0.0  0.0      0     0 ?        S    13:58   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   13:58   0:00  \_ [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   13:58   0:00  \_ [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   13:58   0:00  \_ [slub_flushwq]
root         981  0.0  0.2  15420  9200 ?        Ss   13:58   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 st
root        1479  0.4  0.2  17444 11380 ?        Ss   14:00   0:29  \_ sshd: root@pts/0
root        1528  0.0  0.1   9176  6068 pts/0    Ss   14:00   0:00  |   \_ -bash
root       39641  0.0  0.0  10404  3752 pts/0    R+   15:48   0:00  |   |   \_ ps auxf
root       35297  0.4  0.0   7368  3656 ?        Ss   15:36   0:03  |   \_ bash -c while [ -d /proc/$PPID ]; do slee
root       39642  0.0  0.0   5768  1012 ?        S    15:48   0:00  |       \_ sleep 1
root       13711  0.0  0.2  17444 11324 ?        Ss   14:35   0:01  \_ sshd: root@pts/1
root       13769  0.0  0.1   8916  5820 pts/1    Ss+  14:35   0:00      \_ -bash
root         990  0.0  0.2 317012 11756 ?        Ssl  13:58   0:00 /usr/sbin/ModemManager
root        1008  0.0  0.5 109856 21664 ?        Ssl  13:58   0:00 /usr/bin/python3 /usr/share/unattended-upgrades/u
 
 
# 查看进程信息(prtstat)
# 查看单个进程的详细信息
[root@Rocky8 ~]# prtstat 911
Process: systemd-network                State: S (sleeping)
  CPU#:  0              TTY: 0:0        Threads: 1
Process, Group and Session IDs
  Process ID: 911                 Parent ID: 1
    Group ID: 911                Session ID: 911
  T Group ID: -1
 
Page Faults
  This Process    (minor major):      716        20
  Child Processes (minor major):        0         0
CPU Times
  This Process    (user system guest blkio):   0.03   0.08   0.00   0.00
  Child processes (user system guest):         0.00   0.00   0.00
Memory
  Vsize:       16 MB
  RSS:         8396 kB                   RSS Limit: 18446744073709 MB
  Code Start:  0x55d1f13e6000            Code Stop:  0x55d1f1493801
  Stack Start: 0x7ffe53c83d10
  Stack Pointer (ESP):          0        Inst Pointer (EIP):          0
Scheduling
  Policy: normal
  Nice:   0              RT Priority: 0 (non RT)
 
 
# 进程树(pstree):查看进程的父子关系
# 查看进程
[root@Rocky8 ~]# pstree -p
systemd(1)─┬─ModemManager(990)─┬─{ModemManager}(1016)
           │                   └─{ModemManager}(1019)
           ├─VGAuthService(818)
           ├─cron(924)
           ├─dbus-daemon(925)
           ├─irqbalance(931)───{irqbalance}(966)
           ├─login(960)───bash(1438)
           ├─multipathd(571)─┬─{multipathd}(593)
           │                 ├─{multipathd}(597)
           │                 ├─{multipathd}(598)
           │                 ├─{multipathd}(599)
           │                 ├─{multipathd}(600)
           │                 └─{multipathd}(601)
           ├─networkd-dispat(932)
           ├─nginx(1013)─┬─nginx(1014)
           │             └─nginx(1015)
           ├─polkitd(934)─┬─{polkitd}(967)
           │              └─{polkitd}(980)
           ├─rsyslogd(935)─┬─{rsyslogd}(953)
# 查看进程中的用户切换
[root@Rocky8 ~]# pstree -u
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─VGAuthService
        ├─cron
        ├─dbus-daemon(messagebus)
        ├─irqbalance───{irqbalance}
        ├─login───bash
        ├─multipathd───6*[{multipathd}]
        ├─networkd-dispat
        ├─nginx───2*[nginx(www-data)]
        ├─polkitd───2*[{polkitd}]
        ├─rsyslogd(syslog)───3*[{rsyslogd}]
        ├─sendmail-mta
        ├─snapd───10*[{snapd}]
        ├─sshd─┬─sshd─┬─bash───su───bash(xie)───pstree
        │      │      └─bash───sleep
        │      └─sshd───bash
        ├─systemd───(sd-pam)
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-network(systemd-network)
        ├─systemd-resolve(systemd-resolve)
        ├─systemd-timesyn(systemd-timesync)───{systemd-timesyn}
        ├─systemd-udevd
        ├─udisksd───4*[{udisksd}]
        ├─unattended-upgr───{unattended-upgr}
        └─vmtoolsd───3*[{vmtoolsd}]
 
 
# 搜索进程(pgrep)
# 查看是否有java程序在运行
[root@Rocky8 ~]# ps aux |grep java
root       43538  0.0  0.0   6476  2324 pts/0    S+   15:59   0:00 grep --color=auto java
# 搜索xie有关的程序编号
[root@Rocky8 ~]# pgrep -u xie
43971
44107
[root@Rocky8 ~]# pgrep -au xie
43971 -bash
44107 ping 192.168.100.134
 
 
# pidof:获取程序的进程编号
[root@Rocky8 ~]# pidof passwd
44866
 
 
# 负载查询(uptime)
[root@Rocky8 ~]# uptime                             
16:10:47 up  2:12,  3 users,  load average: 0.30, 0.27, 0.27 #------>不论cpu的和是多少超过五都不行
 
 
# 显示cpu相关统计(mpstat)
# 安装:yum -y install sysstat
# 显示当前CUP的使用情况(steal->被虚拟机所使用的时间,被盗取的时间)
[root@Rocky8 ~]# mpstat
Linux 5.15.0-58-generic (Ubuntu.xie.org)        5/10/2023      _x86_64_        (2 CPU)
 
04:28:02 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:28:02 PM  all    0.33    0.01    1.33    0.08    0.00    0.09    0.00    0.00    0.00   98.16
 
[root@Rocky8 ~]# mpstat
Linux 5.14.0-162.6.1.el9_1.x86_64 (localhost.localdomain)       02/10/2023      _x86_64_        (2 CPU)
 
04:27:53 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:27:53 PM  all    0.26    0.02    0.46    0.19    0.61    0.14    0.00    0.00    0.00   98.32
# 每一秒更新一次cup使用的情况
[root@Rocky8 ~]# mpstat 1
Linux 5.15.0-58-generic (Ubuntu.xie.org)        05/10/2023      _x86_64_        (2 CPU)
 
04:33:45 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:33:46 PM  all    0.50    0.00    2.01    0.00    0.00    0.50    0.00    0.00    0.00   96.98
04:33:47 PM  all    0.00    0.00    0.50    0.00    0.00    0.50    0.00    0.00    0.00   98.99
04:33:48 PM  all    1.01    0.00    1.52    0.00    0.00    0.51    0.00    0.00    0.00   96.97
04:33:49 PM  all    0.51    0.00    1.52    0.00    0.00    0.00    0.00    0.00    0.00   97.98
04:33:50 PM  all    0.51    0.00    1.52    0.00    0.00    0.00    0.00    0.00    0.00   97.97
04:33:51 PM  all    0.00    0.00    1.00    0.00    0.00    0.50    0.00    0.00    0.00   98.50
04:33:52 PM  all    0.00    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   99.50
04:33:53 PM  all    0.00    0.00    0.51    0.00    0.00    0.00    0.00    0.00    0.00   99.49
04:33:54 PM  all    0.00    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   99.50
04:33:55 PM  all    0.00    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   99.50
^CAverage:     all    0.25    0.00    1.01    0.00    0.00    0.20    0.00    0.00    0.00   98.54
 
 
# 查看进程实时状态top和htop
# top:实时显示进程的情况
[root@Rocky8 ~]# top
top - 16:35:54 up  2:37,  3 users,  load average: 0.24, 0.22, 0.25
Tasks: 218 total(总共的进程数),   1 running(运行的进程), 217 sleeping(睡觉中),   0 stopped(停止态),   0 zombie(僵尸态)
%Cpu(s):  0.3 us(用户空间),  1.0 sy(内核空间),  0.0 ni(调整优先级), 98.7 id(空闲),  0.0 wa(io等待),  0.0 hi(硬中断),  0.0 si(软中断),  0.0 st(被盗取时间)
MiB Mem :   3889.8 total(内存大小),   2984.0 free(可用内存),    336.7 used(已经使用内存),    569.1 buff/cache(被占用内存)
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   3307.4 avail Mem
 
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    571 root      rt   0  355048  27652   9072 S   0.3   0.7   0:02.62 multipathd
    819 root      20   0  314900   9292   7724 S   0.3   0.2   0:22.55 vmtoolsd
   1479 root      20   0   17580  11436   8664 S   0.3   0.3   0:37.91 sshd
  53821 root      20   0    7368   3608   3348 S   0.3   0.1   0:00.45 bash
  54349 root      20   0       0      0      0 I   0.3   0.0   0:00.14 kworker/0:1-events
      1 root      20   0  167680  13152   8280 S   0.0   0.3   0:04.79 systemd
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.06 kthreadd
在top运行时:
帮助:h或?,按q或esc退出帮助
排序:
P:%cup 排序
M:%MEM 排序
T:累计占据CUP时长,TIME+
top选项
-d  :指定刷新时间间隔,默认3-b:全部显示所有进程
-n:刷新多少次后退出
-H:线程模式
-p:指定进程号
只显示线程的信息
 
# htop 安装:yum -y install htop
 
 
# free:显示磁盘信息
[root@Rocky8 ~]# free -h
               total        used        free      shared  buff/cache   available
Mem:           1.7Gi       1.2Gi       292Mi       8.0Mi       429Mi       551Mi
Swap:          2.0Gi       265Mi       1.8Gi
 
 
# 进程对应的内存映射pmap:显示进程和内存的使用用情况
[root@Rocky8 ~]# pmap 47049
47049:   -bash
00005614fa8c8000    188K r---- bash
00005614fa8f7000    892K r-x-- bash
00005614fa9d6000    232K r---- bash
00005614faa11000     16K r---- bash
00005614faa15000     36K rw--- bash
00005614faa1e000     44K rw---   [ anon ]
00005614fac65000   1548K rw---   [ anon ]
00007f4f76177000   2980K r---- locale-archive
00007f4f76460000     12K rw---   [ anon ]
00007f4f76463000    160K r---- libc.so.6
00007f4f7648b000   1620K r-x-- libc.so.6
00007f4f76620000    352K r---- libc.so.6
00007f4f76678000     16K r---- libc.so.6
00007f4f7667c000      8K rw--- libc.so.6
00007f4f7667e000     52K rw---   [ anon ]
 
 
# vmstat:查看虚拟内存
[root@Rocky8 ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 3046604  61216 526444    0    0    11     3   87  117  0  1 99  0  0
 
 
# iotop:监视磁盘I/O   安装:yum -y install iotop
 
 
# 显示网络宽带使用情况(iftop):查看网卡
[root@Rocky8 ~]# iftop -n
 
 
# 查看网络实时吞吐量(nload)
[root@localhost ~]# nload
 
 
 
# 查看进程网络带宽的使用情况(nethogs):可以看到程序和网络带宽情况
[root@Rocky8 ~]# nethogs
 
 
# 网络监视工具(iptraf-ng)
[root@Rocky8 ~]# iptraf-ng
 
 
# 系统资源统计(dstat):可代替vmstat
[root@Rocky8 ~]# dstat
You did not select any stats, using -cdngy by default.
----total-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read  writ| recv  send|  in   out | int   csw
  0   0  98   0   0|   0     0 | 319B 1268B|   0     0 | 279   358
  1   1  98   0   0|   0     0 | 320B 1094B|   0     0 | 272   358
  1   1  97   0   0|   0     0 | 474B 1195B|   0     0 | 329   371
  1   1  99   0   0|   0     0 | 538B 1267B|   0     0 | 274   354
  1   1  98   0   0|  64k    0 | 320B 1078B|   0     0 | 438   483
  0   0  99   0   0|   0     0 | 320B 1077B|   0     0 | 275   367
  0   1  99   0   0|   0     0 | 320B 1063B|   0     0 | 277   359
  0   0  99   0   0|   0     0 | 538B 1164B|   0     0 | 259   360
 
 
# 综合监控工具(glances):可以实现远程监控,监控另一台机器
# 开启服务器
[root@Rocky8 ~]# glances -s
Glances XML-RPC server is running on 0.0.0.0:61209
# 连接远程机器
[root@Rocky8 ~]# glances -c 192.168.100.134
 
 
# 查看进程打开文件(lsof):显示多有进程打开的文件
# 查看22端口是那个程序打开的
[root@Rocky8 ~]# lsof -i :22
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd      956 root    3u  IPv4  22382      0t0  TCP *:ssh (LISTEN)
sshd      956 root    4u  IPv6  22384      0t0  TCP *:ssh (LISTEN)
sshd     2816 root    4u  IPv4  32475      0t0  TCP localhost.localdomain:ssh->192.168.100.1:52681 (ESTABLISHED)
sshd     2830  xie    4u  IPv4  32475      0t0  TCP localhost.localdomain:ssh->192.168.100.1:52681 (ESTABLISHED)
sshd    76590 root    4u  IPv4 155798      0t0  TCP localhost.localdomain:ssh->192.168.100.1:59841 (ESTABLISHED)
sshd    76593  xie    4u  IPv4 155798      0t0  TCP localhost.localdomain:ssh->192.168.100.1:59841 (ESTABLISHED)
# 查看被打开文件
lsof | grep +文件名
 
 
# 新特性(cockpit)
安装:dnf -y install cockpit
启动图形:systemctl enable --now cockpit.socket
作用
监控系统活动(CPU,内存,磁盘IO和网络流量)
查看系统日志条目
查看磁盘分区的容量
查看网络活动(发送和接收)
查看用户账号
检查系统服务的状态
提取已安装应用信息
查看和安装可用更新(如果以root身份登录)并在需要时重新启动系统
打开并使用终端窗口
 
 
# 信号发送kill
[root@Rocky8 ~]# kill -l
 1) SIGHUP(用来加载配置文件)       2) SIGINT(ctrl+c)       3) SIGQUIT(ctrl+'/')      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL(强制杀死真在运行的进程,可能会导致数据丢失)     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
(终止正在运行的进程,默认信号)
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT(继续运行)     19) SIGSTOP(后台休眠)     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX
# 发送信号,加载配置文件
[root@Rocky8 ~]# kill -1 1015 #1015是进程编号
 
CTRL+z:将正在运行的程序放置后台停止,以便终端的继续使用
 
 
 
# jobs:查看后台停止的程序
bg +1:将后台停止状态的进程,变成后台运行的程序
fg:将后台运行的程序放置前台运行

4、任务相关的命令

at


# 一次性任务(at)
# 标准输出和标准错误都不会显示
[root@Rocky8 ~]# at 15:13
warning: commands will be executed using /bin/sh
at> touch /data/at.log
at> <EOT>#CTRL+d:退出
job 1 at Sat Feb 11 15:13:00 2023
 
# 两分钟之后执行任务
[root@Rocky8 ~]# at now+2min
warning: commands will be executed using /bin/sh
at> touch /data/at2.log
at> <EOT>
job 2 at Sat Feb 11 15:19:00 2023
[root@localhost ~]# at -l
2       Sat Feb 11 15:19:00 2023 a root
# 删除计划任务
at -d 2

crontab

# 用户创建的计划任务(crontab)
# 存放地址:/var/spool/cron/
# 执行计划任务
[root@Rocky8 ~]# crontab -e
# 产看计划是否执行
[root@Rocky8 ~]# cat /var/log/cron
# 查看计划任务内容
[root@Rocky8 ~]# crontab -l
PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
* * * * * echo $PATH >> /data/path.log; ip address &> /data/ip.log
# 删除计划任务
[root@Rocky8 ~]# crontab -r
[root@Rocky8 ~]# cat /var/spool/cron
cat: /var/spool/cron: Is a directory
# 指定以xie的用户来执行计划任务
crontab -e -u xie
 
# 控制黑名单和白名单
/etc/cron.{allow,deny}

二、总结索引数组和关联数组,字符串处理,高级变量使用及示例。

1、索引数组

#数值索引:索引的编号从0开始

#声明数组:declare -a NAME

#删除数组:unset NAME

#交互式数组赋值:read -a NAME

#列出所有数组
[root@Rocky8 ~]#declare -a
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_COMPLETION_VERSINFO=([0]="2" [1]="7")
declare -a BASH_LINENO=()
declare -ar BASH_REMATCH=()
declare -a BASH_SOURCE=()
declare -ar BASH_VERSINFO=([0]="4" [1]="4" [2]="20" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -a GROUPS=()
declare -a PIPESTATUS=([0]="0")

2、关联索引

# 声明数组:declare -A NAME
[root@Rocky8 ~]#declare -A N75
[root@Rocky8 ~]#N75[birth]="2022.05.19"
[root@Rocky8 ~]#N75[name]=60
[root@Rocky8 ~]#N75[classname]=room75
[root@Rocky8 ~]#N75[monitor]=ding
[root@Rocky8 ~]#echo ${N75[*]}
2022.05.19 ding 60 room75
[root@Rocky8 ~]#echo ${N75[name]}
60
[root@Rocky8 ~]#echo ${N75[monitor]}
ding
[root@Rocky8 ~]#echo ${N75[birth]}
2022.05.19


# 跳过三个数取四个数
[root@Rocky8 ~]#name=({1..10})
[root@Rocky8 ~]#echo ${name[*]}
1 2 3 4 5 6 7 8 9 10
[root@Rocky8 ~]#echo ${name[*]:3:4}
4 5 6 7


# 查看元素的个数
[root@Rocky8 ~]#echo ${#name[*]}
10
#追加数据
[root@Rocky8 ~]#N75[${#N75[*]}]=11
[root@Rocky8 ~]#echo ${N75[*]}
2022.05.19 ding 11 60 room75

3、字符串处理

# 基于模式取字符串
# 从左到右找到'/'把斜杠和前面的内容删除
[root@Rocky8 ~]#url=http://www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url[*]#*/} //懒惰模式
/www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url[*]##*/} //贪婪模式
index.html


# 从右到左找到'/'把斜杠和后面的内容删除
[root@Rocky8 ~]#url=http://www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url%/*}  //懒惰模式
http://www.baidu.com
[root@Rocky8 ~]#echo ${url%/}  //懒惰模式
http://www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url%%/*}  //贪婪模式
http:
[root@Rocky8 ~]#echo ${url%%/}  //贪婪模式
http://www.baidu.com/index.html

#查找替换
[root@Rocky8 ~]#echo ${url}
http://www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url/w/2}  //懒惰模式
http://2ww.baidu.com/index.html
[root@Rocky8 ~]#echo ${url//w/2}  //贪婪模式
http://222.baidu.com/index.html

#删除字符串
[root@Rocky8 ~]#echo ${url}
http://www.baidu.com/index.html
[root@Rocky8 ~]#echo ${url/w}
http://ww.baidu.com/index.html
[root@Rocky8 ~]#echo ${url//w}
http://.baidu.com/index.html

#将小写字母转换为大写字母
[root@Rocky8 ~]#echo ${url^^}
HTTP://WWW.BAIDU.COM/INDEX.HTML
#将大写字母转换为小写字母
[root@Rocky8 ~]#echo ${url,,}
http://www.baidu.com/index.html

三、求10个随机数的最大值与最小值。

[root@Rocky8 script]#vim  test3.sh
#!/bin/bash

max=0
min=100

for i in {1..10}
do
    num=$RANDOM
    echo "第 $i 个随机数: $num"
    if [ $num -gt $max ]; then
        max=$num
    fi
    if [ $num -lt $min ]; then
        min=$num
    fi
done

echo "最大值是 $max"
echo "最小值是 $min"
#验证结果
[root@Rocky8 script]#bash test3.sh
第 1 个随机数: 81162 个随机数: 1353 个随机数: 171314 个随机数: 252705 个随机数: 217006 个随机数: 150977 个随机数: 246498 个随机数: 25259 个随机数: 1099310 个随机数: 14115
最大值是 25270
最小值是 100

四、 使用递归调用,完成阶乘算法实现。

[root@Rocky8 script]#vim +13 test2.sh
  1 #!/bin/bash
  2 # **********************************************************
  3 # * Author        : DingBaoHang
  4 # * Email         : m15269032515@163.com
  5 # * Create time   : 2023-05-16 15:25
  6 # * Filename      : test2.sh
  7 # * Description   :
  8 # **********************************************************
  9
 10 function factorial {
 11     if [ $1 -eq 1 ]; then
 12         echo 1
 13     else
 14         local prev=$(factorial $(( $1 - 1 )))
 15         echo $(( $1 * $prev ))
 16     fi
 17 }
 18
 19 read -p "请输入一个正整数:" num
 20 result=$(factorial $num)
 21 echo "$num! = $result"

#结果验证
[root@Rocky8 script]#bash test2.sh
请输入一个正整数:6
6! = 720

五、解析进程和线程的区别?

进程(Process)是操作系统中的基本概念,它是系统进行资源分配和调度的基本单位,是正在运行程序的实例。进程拥有自己的地址空间、内存、文件描述符、状态等信息,进程之间相互独立,互不干扰。

线程(Thread)是进程中的一个执行流程,它共享进程的资源,包括内存、文件描述符、状态等。线程拥有自己的栈和局部变量,但是它们共享全局变量和静态变量等资源,线程之间的切换需要切换上下文。一个进程中可以包含多个线程,这些线程都共享该进程的资源。

下面是进程和线程的主要区别:

1. 资源占用:进程独立占有一定的系统资源,而线程则共享自己所在进程的资源。

2. 栈和局部变量:线程拥有自己的栈和局部变量,但是多个线程之间共享全局变量和静态变量。而进程拥有自己的独立空间,不会共享栈和局部变量。

3. 调度:进程调度的开销相对较大,因为每个进程都是独立的。而线程的调度相对较轻,在多核 CPU 下线程可以同时运行。

4. 独立性:进程具有相对独立性,进程之间可以互相通信。而线程依赖于所属的进程,多个线程之间的切换需要切换上下文,并且线程之间的通信需要通过进程提供的机制来实现。

六、解析进程的结构

一个进程是由操作系统管理的程序运行实例。一个进程包括三部分内容:进程控制块、程序段、数据段。

1. 进程控制块(PCB,Process Control Block):也被称为进程描述信息,它是系统分配给每个进程的数据结构,用于统一管理系统中所有的进程。它包含了进程的相关信息,如进程状态、PC、CPU寄存器的值、进程ID、进程优先级、文件描述符、所拥有的资源等。

2. 程序段:也被称为代码段,指的是进程所要执行的程序代码。

3. 数据段:也称为全局变量区、静态变量区,指的是进程中的数据和堆栈空间。其中数据段包括了全局变量和静态变量,堆是动态分配的内存区,堆的大小不固定并且可以动态增长,在进程中也属于数据段,而栈是记录程序执行状态的内存区,也是数据段的一部分。

除了上述内容以外,进程还会占用一些系统资源,如内存、文件描述符、定时器等。

七、解析磁盘中的代码如何在计算机上运行的?

磁盘中的代码需要被加载到计算机内存中,才能被计算机CPU执行。下面是代码如何在计算机上运行的一些简要步骤:

1. 编写代码:程序员使用各种编程语言(如C、Java、Python等)编写代码。

2. 编译或解释代码:代码需要编译或解释后才能被计算机CPU读取和执行。编译器会将程序源码翻译成二进制指令,而解释器则会逐行解释源代码并执行。

3. 存储代码:编译或解释后的代码被存储在磁盘中,通常以可执行文件的形式存在,如.EXE、.BIN、.ELF等文件格式。

4. 加载代码:存储在磁盘中的可执行文件需要被加载到计算机内存中,以便CPU能够访问程序的代码和数据。操作系统负责加载可执行文件,并将其映射成进程。

5. 执行代码:一旦代码被加载到内存中形成进程,即可由CPU执行。CPU会依次执行代码中的指令,直到程序结束。

在代码执行阶段,CPU会对指令进行解码、执行、跳转等操作,将进程中的代码逐行执行,同时还会执行相应的I/O操作等,最终完成软件应用程序的功能。

需要注意的是,在实际的计算机系统中,上述过程可能会受到访问权限、内存限制、硬件环境等因素的影响,在执行代码前还可能需要进行诸如链接、依赖检查等操作。

八、总结OOM原理,及处理方法

OOM(Out Of Memory)是指当操作系统不能再足够分配给进程所需内存时,会触发OOM机制,操作系统会尝试释放一些内存资源,并选择终止一些进程来解决内存使用问题。

OOM的原理可以简单地描述如下:

1. 当一个操作系统中的进程申请内存时,操作系统会分配给它一段虚拟内存地址空间,并标记为虚拟内存地址空间中的一部分已经被使用。

2. 如果操作系统中的进程继续申请内存而操作系统无法再分配更多的物理内存,它就会从已使用的虚拟内存中选择一个部分,将其释放,从而腾出一些内存。

3. 如果操作系统无法释放任何已使用的虚拟内存并且仍然无法为该进程分配更多内存,操作系统就会选择杀死一个消耗内存量较大的进程来释放内存。

常见的OOM处理方法包括:

1. 内存增加:增加系统内存可以缓解内存问题,并且可以增加系统响应能力和吞吐量。

2. 配置虚拟内存:在内存极度紧缺的情况下,可以通过配置虚拟内存,将一部分磁盘空间作为虚拟内存空间使用,来扩充内存容量。

3. 杀死进程:由于OOM机制会终止一些进程,因此可以通过杀死占用内存较大的进程来腾出一些内存资源。

4. 优化应用程序:优化应用程序代码设计,包括减少内存分配、避免内存泄露、优化数据结构、缓存数据、关闭不必要的服务等,都有助于降低内存使用。

设置内核参数,不允许内存申请过量(此方法一般不推荐)

[root@Rocky8 script]#echo 2 > /proc/sys/vm/overcommit_memory
[root@Rocky8 script]#echo 80 > /proc/sys/vm/overcommit_ratio
[root@Rocky8 script]#echo 2 > /proc/sys/vm/panic_on_oom 

九、 结合进程管理命令,说明进程各种状态

ps命令

#ps命令常用于查看进程的当前状态。ps命令输出的STAT字段用于表示进程的状态
R:运行中(Running)。
S:休眠(Sleeping),也称为“可中断睡眠”。
D:不可中断休眠(Uninterruptible sleep)。
T:停止(Stopped)。
Z:僵尸进程(Zombie)。

top命令

#top可以监控系统的进程、CPU、内存等资源占用情况
[root@Rocky8 script]#top
top - 16:23:27 up 3 days, 18:36,  2 users,  load average: 0.00, 0.00, 0.00
Tasks: 245 total,   1 running, 244 sleeping,   0 stopped,   0 zombie

running:正在运行的进程。
sleeping:正在等待事件的进程。
stopped:已停止的进程。
zombie:僵尸进程。

kill命令

SIGTERM:请求进程终止,通常是正常方式关闭。
SIGKILL:强制结束进程。
#实例
[root@Rocky8 ~]#ping 192.168.188.100
[root@Rocky8 script]#ps aux |grep ping
root      135312  0.0  0.1 242284  2344 pts/0    S+   16:25   0:00 ping 192.168.188.100
root      135404  0.0  0.0 221940  1100 pts/1    S+   16:26   0:00 grep --color=auto ping
[root@Rocky8 script]#kill 135312

pkill命令

pkill命令:可以通过进程名、用户ID等信息来找到并杀死进程。

十、说明IPC通信和RPC通信实现的方式

IPC(Inter-Process Communication,进程间通信)和 RPC(Remote Procedure Call,远程过程调用)是两种在进程间进行交互的通信方式。

一、IPC通信实现方式:

1. 管道(Pipe):管道是进程间通信的一种简单方式,允许在两个或多个进程之间传递数据。它主要基于UNIX文件系统中的一种特殊文件类型,可以将一个进程的输出直接发送到另一个进程的输入,从而实现两个进程之间的通信。

2. 信号(Signal):可以用来通知进程发生了某些事情,如某个进程结束了执行,发生了错误等等。通过使用信号,一个进程可以向其他进程发送一个信号,告诉它某些事情已经发生了,无论是好还是坏。

3. 管理共享内存(Shared Memory):共享内存允许多个进程访问同一块内存区域,从而允许它们相互交换信息,而不需要使用其他通信方式。共享内存通常被用于大量数据的传输,特别是在高速数据的环境中非常有用。

4. 套接字(Socket):套接字是在网络中传输数据的一种通用方法。它允许不同的进程在同一网络内传输数据,同时可以进行双向通信,可以通过网络连接远程进程。

二、RPC通信实现方式:

RPC是远程过程调用的意思,在分布式计算中使用RPC来处理远程调用请求。其主要实现方式如下:

1. 远程服务接口定义(Remote Service Interface Definition):RPC的首要任务是定义远程服务接口,以便客户端应用程序可以透明地调用服务端应用程序。

2. 生成RPC绑定代码(Generating RPC Binding Code):基于定义的远程服务接口,可以生成必要的RPC绑定代码,使客户端和服务器能够进行通信和相互调用。这些代码最初是由RPC语言编写的,然后被转换为适当的语言和协议。

3. 连接管理(Connection Management):RPC通信需要建立连接,以便客户端和服务器之间可以通信,客户端会自动建立一个连接对象,连接的管理通常通过TCP/IP来完成。

4. 编码与解码(Encoding and Decoding):客户端和服务器之间需要进行数据通信,但是它们使用的是不同的内存空间,这意味着要对数据进行编码和解码,在客户机和服务器之间传递调用过程的参数。

十一、通过mkfifo, cat, 来解释秒杀的并发问题,如何通过队列解决的?最好结合图形。说明消息队列的作用?

假设某商品进行秒杀活动,每秒钟有数千个用户来尝试抢购,如果所有请求都直接访问数据库进行读写,那么数据库可能无法承受如此高的并发访问量,导致数据库宕机或响应时间过长,进而影响用户体验。为了解决这个问题,可以使用FIFO(也称为命名管道)和消息队列。具体说明如下:

1. 使用FIFO和cat解释秒杀的并发问题。

假设在该秒杀活动中,用户OA、OB、OC和OD同时发起秒杀请求,而所有请求都会先进入FIFO中,如下图所示:

![image-20211018144742308](https://i.loli.net/2021/10/18/vUc3jbqFxAHXSWZ.png)

在FIFO中,用户请求将被排队,直到服务器处理这些请求。此时,通过简单的cat命令可以实时显示FIFO中存储的请求。

2. 通过使用队列解决并发问题

使用队列可以有效地解决高并发请求问题。下图展示了如何使用队列处理并发请求的过程:

![image-20211018144905298](https://i.loli.net/2021/10/18/vx9k3QH7Yn5T8ez.png)

在该图中,所有的请求先被发送到消息队列中,然后服务端按照请求的先后顺序逐个处理这些请求。与FIFO相比,队列还可以有更多的控制选项,例如队列的容量、处理请求的速度等。

3. 消息队列的作用

消息队列(Message Queue)提供了一种方法,让进程通过一种可靠的、异步的方式发送和接收数据。通过使用消息队列,可以减轻系统资源的压力,实现进程间通信,同时增加系统的可靠性。消息队列的具体作用如下:

- 异步传输:消息队列允许发送者异步地将消息发送到队列中,从而可以尽可能快地处理请求,闲置的进程可以立即处理下一条请求。
- 应用解耦:通过使用消息队列,不同的应用程序可以解耦,避免了应用程序之间因解耦不同而导致的侵入性的改变。
- 可靠性:消息队列通常会确保消息被确实传递到队列中,并且仅当消息在队列上被接收方接收时,它才会被删除,从而确保可靠性和数据的一致性。


十三、总结内核设计流派及特点

宏内核和微内核

1. 宏内核又称“单内核”(Monolithic Kernel)如unix、linux

单内核是最常见和传统的内核设计流派之一,把所有的操作系统都放入到内核中。所有功能都集成到同一个程序,分层实现不同的功能,系统庞大复杂,linux实际上是单内核实现了模块化,相当于吸收了微内核的优点。

2. 微内核(Microkernel)如windows、Solaris、harmonyOS

微内核将内核分解为多个小的、较简单的组件,不同的组件运行在用户态和内核态之间。通常,只有最基本的操作系统服务(如进程通信机制、内存管理、文件管理等)放在内核中,而其他服务则被封装成用户态进程或用户态服务。微内核的主要优点是能够实现更好的灵活性和可配置性,同时也增加了操作系统安全和可靠性。然而,微内核也会导致性能上的额外开销,由于操作系统服务和应用程序进程之间的通信,造成系统资源的额外开销,性能差因此在高性能和关键应用中应谨慎使用。

十四、总结centos 6 启动流程,grub工作流程

CentOS 6是使用SysVinit初始化进程的Linux操作系统,其启动流程可以简单地总结为:

1. BIOS(基本输入输出系统):加载 BIOS的硬件信息,获取第一个启动设备。 

2. MBR(主引导记录):BIOS 会找到一个指定的硬盘(如/dev/sda),并通过磁盘的第一个扇区中的 MBR(主引导记录)来引导启动。MBR 是一个特殊的分区,它包含了引导加载程序(grub)的启动信息
3. GRUB(GRand Unified Bootloader):MBR 内的引导程序启动后,会加载 bootloader(启动加载程序),CentOs6 使用的是 GRUB。GRUB 提供了启动选项的选择、内核和模块的加载等功能。

4. 内核加载:通过 GRUB 选择操作系统后,GRUB 会找到相应的内核文件 vmlinuz。接着,GRUB 会将内核文件从硬盘中加载到内存中。

5. 内核初始化:内核文件加载到内存中后,控制权交给内核。内核被加载后,开始初始化系统并加载必要的模块,如硬件驱动程序、内存管理、文件系统等等。

6. 启动第一个用户空间进程:当内核初始化完成以后,它会启动第一个用户态进程 init,接下来所有的用户进程都由 init 进程来管理。

#在以上启动流程中,grub的工作流程如下:

1. 加载 grub.conf 文件:GRUB的配置文件为 grub.conf,它通常存放在/boot/grub目录下。在启动时,GRUB 会读取该配置文件。

2. 显示启动菜单:根据 grub.conf 文件,GRUB 会显示启动菜单,让用户选择需要启动的操作系统。

3. 加载内核:GRUB会在菜单中读取用户选择的要启动的内核文件,并将其加载到内存中。

4. 加载 initramfs 文件:当内核文件被加载到内存中后,GRUB 会一同加载 initramfs 文件,该文件包含了一些必要的模块和工具,用于内核启动前的初始化过程。

5. 控制权交给内核:GRUB 会将控制权交给内核,由内核来进一步初始化系统和加载必要的模块。

简而言之centos 6的启动总结为POST(上电自检)
–GRUB 1阶段MBR446–GRUB1.5MBR之后的空间(提供grub2文件所有分区的文件系统)
–GRUB 2阶段(grub.conf)
–kernel(initramfs.img)–根分区–/sbin/init–/etc/inittab–/etc/rc.sysinit(系统初始化脚本)
–/etc/rc.d/rc–/etc/rcN.d/K,S(/etc/init.d/)–/etc/rc.local–login登录

十五、手写chkconfig服务脚本,可以实现服务的开始,停止,重启。

十六、总结systemd服务配置文件

十七、总结system启动流程

UEF或BIOS初始化,运行POST开机自检
选择启动设备
引导装载程序,centOS7是grub2加载程序的配置文件:
	/etc/grub.d/
	/etc/default/grub
	/boot/grub2/grub.cfg
加载initramfs驱动模块(可以实现根文件系统的挂载)
加载内核选项
内核初始化,centOS使用systemd代替init
执行initrd.target所有单元,包括挂载/etc/fstab
从initasmfs根文件系统切换到磁盘根目录
systemd执行默认target配置,配置文件/etc/systemd/system/default.target
systemd执行sysinit.target初始化系统及basic.target准备操作系统
systemd启动multi-user.target下的本机于服务器服务
systemd执行multi-user.target下的/etc/rc.d/rc.local
ststemd执行multi-user.target下的getty.target及登录服务
systemd执行graphical需要的服务

十八、总结awk工作原理,awk命令,选项,示例。

1、awk工作原理

逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式
或者条件执行编辑命令。

2、awk命令:

 awk [-F field-separator] 'commands' input-file(s)其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

十九、 总结awk的数组,函数。

1、数组:

去重

root@Ubuntu:~# cat /data/test.txt
a
b
c
a
b
c
a
b
c
d
r
s
d
root@Ubuntu:~# awk '!line[$0]++' /data/test.txt
a
b
c
d
r
s

2、函数:

生成随机数

root@Ubuntu:~# awk 'BEGIN{srand();print rand()}'
0.0253289
root@Ubuntu:~# awk 'BEGIN{srand();print rand()}'
0.778805

1-100随机数

root@Ubuntu:~# awk 'BEGIN{srand();print int(rand()*100)}'
71
root@Ubuntu:~# awk 'BEGIN{srand();print int(rand()*100)}'
94

字符串处理

length([s]):返回指定字符串长度
sub(r,s,[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配的内容替换成s,懒惰模式
gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
split(s,array,[r]):以r为分割符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二人格索引值为2...
system():括号里能执行linux命令
systime():当前时间到1970-1-1的秒数
strftime():指定时间格式

自定义函数

形参:定义函数时的参数,占位符
实参:使用函数实际正在使用的参数

root@Ubuntu:~# cat /data/a.awk
BEGIN{print strftime("%Y-%m-%d T%H:%M",systime())}
root@Ubuntu:~# awk -f /data/a.awk
2023-02-15 T14:23
 
root@Ubuntu:~# cat test.awk
function max(x,y) {
        x>y?var=x:var=y
        return var
}
BEGIN{print max(a,b)}
 
root@Ubuntu:~# awk -v a=10 -v b=30 -f test.awk
30
root@Ubuntu:~# awk -v a=100 -v b=30 -f test.awk
100
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大海绵啤酒肚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值