Shell 技巧

Shell 技巧

[TOC]

开机挂在iso文件

修改 /etc/fstab

/root/centos7.iso /root/mnt udf,iso9660 user,loop 0 0

挂载目录

mount --bind /test1 /test2

sudo OR root

保存 sudo 密码

PASS="intel123"
echo ${PASS} | sudo -S "$@"

# cache 中不保存 sudo密码
sudo -K 

read 输入密码不回显

stty -echo
read -p "Password:" pass
stty echo

root 或sudo 执行

PROXY="http://proxy-prc.intel.com:911"

export http_proxy=$PROXY
export https_proxy=$PROXY

# rerun the script under sudo if not ran under root
(( EUID != 0 )) && exec sudo -E -- "$0" "$@"
export | grep -i proxy

sudo 不用密码

修改/etc/sudoers

SUSE, CentOS6
media       ALL=(ALL)   NOPASSWD:  ALL
CentOS7
%wheel  ALL=(ALL)       NOPASSWD: ALL

media 用户得要加入wheel组 usermod -G wheel media

Ubuntu
%sudo       ALL=NOPASSWD:  ALL

Terminal 有颜色

ECHO_PREFIX_INFO="\033[1;32;40mINFO...\033[0;0m"
ECHO_PREFIX_ERROR="\033[1;31;40mError...\033[0;0m"

# Try command  for test command result.
function try_command {
    "$@"
    status=$?
    if [ $status -ne 0 ]; then
        echo -e $ECHO_PREFIX_ERROR "ERROR with \"$@\", Return status $status."
        exit $status
    fi
    return $status
}

ssh

解决ssh key冲突

Add correct host key in /home/media/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /home/media/.ssh/known_hosts:8

  1. 用ssh-keygen 删除
ssh-keygen -f "/home/media/.ssh/known_hosts" -R 10.239.173.13 
  1. 删除known_hosts第8行
vim /home/media/.ssh/known_hosts +8

ssh 利用远程机器的key

1.得到要访问的服务器的私钥 id_rsa.bzhux 放到 ~/.ssh/ 下

cp id_rsa.bzhux ~/.ssh/
chmod 600 ~/.ssh/id_rsa.bzhux

新建一个 ~/.ssh/config

touch ~/.ssh/config
chmod 600 ~/.ssh/config

写入内容

# bzhux@myhost.com
Host bzhux
  HostName myhost
  Port 22
  User bzhux
  IdentityFile ~/.ssh/id_rsa.bzhux
ssh bzhux@myhost.com

ssh无密码登陆

方法1

ssh-keygen
#ssh-copy-id -u user -i ~/.ssh/id_rsa.pub user@host
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
ssh user@host

方法2 本地机器 生成ssh key, 在~/.ssh下 生成 ~/.ssh/id_rsa.pub 和 ~/.ssh/id_rsa

ssh-keygen

远程机器

cd ~/.ssh/
touch authorized_keys
chmod 600 authorized_keys
  1. 把本地机器上的 ~/.ssh/id_res.pub 的内容追加到 远程机器上的 ~/.ssh/authorized_keys
  2. 估计2种方式是一样的

取消弹出信息

Are you sure you want to continue connecting (yes/no)?

修改 /etc/ssh/ssh_config

StrictHostKeyChecking no

ssh 正向代理

参考这里

 +--------------+       +--------------+      +-----------------+
 | 192.168.1.2  |       | test@8.8.8.8 |      |    8.8.4.4      |
 |              |------>|              |----> |80               |
 +--------------+       +--------------+      +-----------------+
    | 8080   |
    +--------+
        ^
        |
        |
+-------+------------------+
| http://192.168.1.2:8080  |
+--------------------------+

在192.168.1.2上执行. Client就可以用 http://192.168.1.2:8080 访问了

ssh -L 192.168.1.2:8080:8.8.4.4:80 test@8.8.8.8

如果是转发8.8.4.4上面ssh的22端口

ssh -L 192.168.1.2:8888:8.8.4.4:22 test@8.8.8.8

# client上 -p 指定端口. 这里的user是 8.8.4.4上面的user
ssh -p 8888 user@192.168.1.2

ssh反向代理

+----------------+          +---------------------+
|  192.168.1.2   +--------> | test@8.8.8.8    8080|
+----------------+          +---------------------+
                |                               ^
                |                               |
                v                               |
+----------------+          +----------------------+
|192.168.1.3   80|          |  http://8.8.8.8/8080 |
+----------------+          +----------------------+

在192.168.1.2上执行

ssh -R 8.8.8.8:8080:192.168.1.3:80 test@8.8.8.8

反向代理 默认只绑定到 localhost上, 通过IP不能访问, 以下方式能解决

/etc/ssh/sshd_config 添加这条 并重启ssh服务

GatewayPorts clientspecified
sudo systemctl restart sshd.service
# sudo /etc/init.d/ssh restart

连接自己的事例

# 服务器上连接到自己
ssh -R 192.168.1.2:8888:192.168.1.3:22 user@192.168.1.2

# client上 -p 指定端口
ssh -p 8888 user@192.168.1.2

文件操作

烧制iso文件到DVD

sudo cdrecord -v -eject dev=/dev/cdwriter driveropts=burnfree CentOS.iso

得到执行脚本的路径

filepath=$(cd "$(dirname "$0")"; pwd)

删除以-开头的文件

touch -- -f
rm ./-f

cp 备份文件

cp some_file_name{,.bak}

文件一行一行读取

cat abc.txt | while read line; do
    echo "[$line]"
done

while read line; do
    echo "[$line]"
done < abc.txt

多行文本

FOLDERS=`cat << EOF
/mnt/WEEKLY-BUILD/STAGING/SMTA/CENTOS
/mnt/WEEKLY-BUILD/STAGING/ASTA/CENTOS
/mnt/WEEKLY-BUILD/STAGING/SNVA/CENTOS
/mnt/WEEKLY-BUILD/STAGING/VCSA/CENTOS
/mnt/WEEKLY-BUILD/STAGING/LIBOA/CENTOS
/mnt/WEEKLY-BUILD/STAGING/Xcoder/CENTOS
EOF`

## write
(
cat << EOF
111111111111111
222222222222222
333333333333333
EOF
) > abc.txt

cat << EOF > xyz.txt
111111111111111
222222222222222
333333333333333
EOF

cat > tab.py <<EOF
#!/usr/local/bin/python
# python tab file
import sys
import readline
import rlcompleter
import atexit
import os
# tab completion
readline.parse_and_bind('tab: complete')
# history file
histfile = os.path.join(os.environ['HOME'], '.pythonhistory')
try:
    readline.read_history_file(histfile)
except IOError:
    pass
atexit.register(readline.write_history_file, histfile)

del os, histfile, readline, rlcompleter
EOF

多行注释

COMMENT_BLOCK=
if [ $COMMENT_BLOCK ]; then
echo "comment2"
echo "comment3"
fi

<<"COMMENT"
echo "command1"
echo "command2"
echo "command3"
COMMENT

将stdout和stderr 输出并重定向到文件

err.sh 2>&1 | tee -a log

比较

统计file1中没有,file2中有的行

grep -vwf file1 file2

sed

windows 文件格式转换到 Linux下

sed -e 's/^M//g' windos_file

^M 是先按 CTRL+V 再按 CTRL+SHIFT+M

n命令

使用n 命令 之后, 停在当前行, 但操作的是下一行的

# 偶数行打印2遍
sed 'n;p' file

#奇数行
sed ‐n 'p;n' test.txt 

#偶数行
sed ‐n 'n;p' test.txt 

N命令

使用N 命令 之后, 停在当前行,操作的是当前行和下一行2行

# 两行用:连接
sed 'N;s/\n/:/g' file

awk

# 计算第一列的平均数
awk 'BEGIN{s=0} {s+=$1} END{print s/NR}'

vim

保存时获得sudo权限

:w !sudo tee %

每行行首,行尾操作

## 在每行行首添加
:%s/^/your_word/

## 在每行行尾添加
:%s/$/your_word/

## 在第2到第5行之间 行首添加 "#"
:2,5 s/^/#/

## 删除每行行尾多余空格
:%s/\s\+$//g

## 删除空行
:g/^$/d

格式化代码

:VG=

全局命令 :g

:[range]g/pattern/command

:g!/pattern/d 删除不匹配行 :v/pattern/d 删除不匹配行 v是in(v)erse的缩写 :g/^$/d 删除空行

:1,20g/^/pu _ 1到20行 每一行插入空行 :g/^[0-9]\{5\}/m$ 匹配行 移动到文件末尾 :g/^[0-9]\{5\}/t$ 匹配行 复制到文件末尾 :g/^/m0 翻转文件中的每一行

:g/^/m0 一行行匹配,匹配第一行时将第一行 m0 放到文件顶部,第二行放到文件顶部,当跑完一遍之后整个文件的每一行就反转了。

win文档转换成linux

  1. :set ff=unix
  2. :%/^M//g 这里的 ^M 是 Ctrl+V, Ctrl+M
  3. dos2unix 命令 dos2unix winFile
  4. sed 命令 sed -i 's/^M//g' 这里的 ^M 是 Ctrl+V, Ctrl+M

sudo 权限不够

sudo 重定向

echo 1 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_all

echo 1 | sudo tee -a xyz.txt 追加到文件

将引号内的内容作为一个字符串执行

sudo sh -c "echo a > 1.txt"

sudo bash -c "echo a > 1.txt" 也可以

Bash 捕获 Ctrl + C

trap 'onCtrlC' INT
function onCtrlC() {
    echo "Ctrl + C is captured"
    exit 0
}

while true; do
    echo "I'm working"
    sleep 1
done

find

find 删除带空格的文件

find . -name '*.html' -print0 | xargs -0 file

find 把带有txt的移动到指定目录

find -iname "*txt*" -exec mv -v {} /home/user \;

find 删除当前目录下超过100天的文件

find . -maxdepth 1 -ctime 100 -exec rm -rf {} \;

Shell数组

s="abc"
ID=(1278 1280 1281 1282)

len=${#ID[*]}
echo $len
for i in $(seq 0 $len); do
    touch ${s}${ID[$i]}
done

ffplay 播放 YUV

ffplay -autoexit -f rawvideo -video_size 176x96 test_stream_176x96.yuv

expect

ssh

#!/usr/bin/expect

set timeout 30
spawn ssh user@localhost
expect {
    "(yes/no)" {
        send "yes\r"; exp_continue
     }
    "*assword" {
        send "123456\r"
    }
}

spawn ls
expect eof

#interact

scp

#!/usr/bin/expect
# script name : testExpect.sh

set timeout 30
set host localhost
set username user
set password 123456
set src_file [lindex $argv 0]
set dest_file [lindex $argv 1]

spawn scp $src_file $username@$host:$dest_file
expect {
    "(yes/no)" {
        send "yes\n"
        expect "*assword" { send "$password\n"}
    }

    "*assword" {
        send "$password\n"
    }
}

expect "100%"
expect eof

ssh + expect

#!/bin/bash

USER="$1"
PASS="$2"
HOST='192.168.0.5'
/usr/bin/expect << EOF
set timeout 60
spawn git clone $USER@$HOST:/home/user/myrepo
expect {
    "(yes/no)" {
        send "yes\n"; exp_continue
     }
    "*assword" {
        send "$PASS\n"
    }
}
expect eof
EOF
cd myrepo/
git checkout master

expect下的组合键

#!/usr/bin/expect
spawn minicom
expect "Press CTRL-A Z for help"
send "\07"      # Ctrl + G
send "0\n"
interact

组合键参考 http://blog.csdn.net/iodoo/article/details/49175749

远程备份

rsync -avrz  --delete --progress media@10.239.128.63:/home/share/VPG-driver .

阻塞下输入

main.sh

read a
echo "aaaa: ${a}"

read b
echo "bbbb: ${b}"
(sleep 2
echo 1
sleep 2
echo 5
) | ./main.sh

看lib的版本

pkg-config --modversion libdrm

git

git-proxy

# Ubuntu
sudo apt-get install socat

# CentOS
sudo yum install socat

/usr/bin/git-proxy

proxy=proxy-shz.intel.com
exec socat STDIO SOCKS4:$proxy:$1:$2

~/.gitconfig

[core]
        gitproxy = none for intel.com
        gitproxy = git-proxy
[http]
        proxy = http://name:password@child-prc.intel.com:914
        sslverify = false
[https]
        proxy = http://name:password@child-prc.intel.com:914

不在gitconfig里设置 [http] 和 [https], 就在终端里设置 export http_proxy=http://name:password@child-prc.intel.com:914 export https_proxy=http://name:password@child-prc.intel.com:914

git 制定key

git.sh

if [ $# -eq 0 ]; then
    echo "Wrapper script that can specify an ssh-key file with the Git command
Usage:
    $0 -i ssh-key-file git-command"
    exit 1
fi

# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0

if [ "$1" = "-i" ]; then
    SSH_KEY=$2; shift; shift
    echo "ssh -i "$SSH_KEY" \"\$@\"" > /tmp/.git_ssh.$$
    chmod +x /tmp/.git_ssh.$$
    export GIT_SSH=/tmp/.git_ssh.$$
fi

# in case the git command is repeated
[ "$1" = "git" ] && shift

# Run the git command
git "$@"
./git.sh -i id_rsa.pub git clone git@$server_ip:xxx.git

踢出已登录用户

[media@localhost WebStream]$ w
 08:46:02 up 1 day, 17:47,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
media    :0       :0               Tue14   ?xdm?  14:44   0.63s gdm-session-worker [pam/gdm-autologin]
media    pts/0    shwdeisgchi123.c Tue15    2.00s  0.08s  0.00s tmux new -s zbq
media    pts/7    shwdeisgchi123.c 08:44    1:41   0.08s  0.08s -bash
[media@localhost WebStream]$ pkill -kill -t pts/7

网络

mount Samba

sudo mount -t cifs //10.239.128.63/bzhux /mnt -o user=media,passwd=intel123

# 像FTP客户端一样使用smbclient, 不加-U 以当前用户名访问
smbclient //192.168.0.1/tmp  -U username%password

# 查看共享文件夹
smbclient -L 198.168.0.1 -U username%password 

wget

下载整个目录

wget --no-check-certificate --user ${USER} --password ${MY_PASSWORD} -r -np -nd ${URL}

建立网桥

sudo apt-get install bridge-utils
sudo brctl addbr br1
sudo brctl addif br1 eth0
sudo ifconfig eth0 0.0.0.0
sudo ifconfig br1 up

删除网桥

sudo ifconfig br1 down
sudo delif br1 eth0
sudo delbr br1

添加默认网关

方法1

#route add -net 10.239.173.0/24 enp1s0f1
#route add -net 192.168.100.0/24 eth0
route add default gw 10.239.173.1

方法2 /etc/sysconfig/network

GATEWAYDEV=enp1s0f1
GATEWAY=10.239.173.1

禁止ping通

临时修改

# 禁止ping
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

# 允许ping
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

永久修改 修改 /etc/sysctl.conf

net.ipv4.icmp_echo_ignore_all=1

生效

sudo sysctl -p

ip 命令

参看这里

开启/关闭网卡

相当于 ifconfig eth0 up/down

ip link set dev eth0 up/down
修改MAC地址
ip link set dev eth0 address 00:01:4f:00:15:f1
查看ip地址
ip addr show
查看路由表
ip route show
网关

添加默认网关

ip route add default via 192.168.137.2

删除默认网关

ip route del default

端口

cat /etc/services

参看远程端口是否打开

nmap ${IP} -p ${PORT}

## 
nc -v ${IP} ${PORT}

telnet ${IP} ${PORT}

bonding

[media@localhost ~]$ uuidgen enp4s0f0
6d226496-1621-4ba2-8c81-baefccb24b60
[media@localhost ~]$ uuidgen enp4s0f1
535e015e-cd2e-4a1b-9b28-85ca03f7cefa

/etc/sysconfig/network-scripts/ifcfg-bond0

TYPE=Bond   #Interface type set to bond
BOOTPROTO=static
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup"  #i set mode to active-backup 
DEFROUTE=yes 
IPADDR=192.168.122.100  #IP address of bond0 interface
NETMASK=255.255.255.0 
GATEWAY=192.168.122.1
IPV4_FAILURE_FATAL=no 
IPV6INIT=no
NAME=bond0
DEVICE=bond0
ONBOOT=yes

/etc/sysconfig/network-scripts/ifcfg-enp4s0f0

TYPE=Ethernet
MASTER=bond0
SLAVE=yes
NAME=enp4s0f0
UUID=6d226496-1621-4ba2-8c81-baefccb24b60
DEVICE=enp4s0f0
ONBOOT=yes

/etc/sysconfig/network-scripts/ifcfg-enp4s0f1

TYPE=Ethernet
MASTER=bond0
SLAVE=yes
NAME=enp4s0f1
UUID=d46459b8-4500-9a0b-79f0c65ca109
DEVICE=enp4s0f1
ONBOOT=yes

teaming

/etc/sysconfig/network-scripts/ifcfg-team0

#BOOTPROTO=static
BOOTPROTO=dhcp
TEAM_CONFIG='{"runner":{"name":"activebackup"},"link_watch":{"name":"ethtool"}}'
NAME=team0
DEVICE=team0
ONBOOT=yes
DEVICETYPE=Team
#IPADDR=192.168.122.120
#NETMASK=255.255.255.0
#GATEWAY=192.168.122.1
#PREFIX=24

/etc/sysconfig/network-scripts/ifcfg-enp4s0f0

TEAM_MASTER=team0
TEAM_PORT_CONFIG='{"prio":99}'
DEVICETYPE=TeamPort
NAME=enp4s0f0
HWADDR=90:e2:ba:4a:33:78
DEVICE=enp4s0f0
ONBOOT=yes

/etc/sysconfig/network-scripts/ifcfg-enp4s0f1

TEAM_MASTER=team0
TEAM_PORT_CONFIG='{"prio":100}'
DEVICETYPE=TeamPort
NAME=enp4s0f1
HWADDR=90:e2:ba:4a:33:79
DEVICE=enp4s0f1
ONBOOT=yes

挂在LVM

sudo lvdisplay
  --- Logical volume ---
  LV Path                /dev/centos_lh/home
  LV Name                home
  VG Name                centos_lh
  LV UUID                1qiRhY-AVX4-Wueh-mUp5-mER0-ISCM-E0wwlp
  LV Write Access        read/write
  LV Creation host, time lh.lm, 2016-08-30 10:58:18 +0800
  LV Status              available
  # open                 1
  LV Size                873.21 GiB
  Current LE             223541
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2
sudo vgchange -ay /dev/centos_lh/home
sudo mount /dev/centos_lh/home /mnt

磁盘

查看磁盘信息

这个有些查不到

# apt-get install -y smartmontools
# yum install -y smartmontools

sudo smartctl -a /dev/sda

这个是系统自带的

udevadm info  --query=all  --name=/dev/sda | grep -i serial

大硬盘格式化及分区

sudo parted /dev/sdb
mklabel gpt 
print
mkpart primary 0 8TB
quit
sudo mkfs.ext4 -T largefile /dev/sdb1

清理缓存

echo 3 > /proc/sys/vm/drop_caches

时间 时区

时间显示用英文

临时生效

export LC_TIME="en_US.UTF-8"

永久生效 修改 /etc/default/locale

LANG="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"

或者

sudo localectl set-locale LANG=en_US.utf8

修改日期 和 时间

## 手动设置
sudo date -s "2016/08/17 14:37:00"

## 与NTP服务器同步
sudo ntpdate corp.intel.com

## 系统时间写入BIOS
sudo hwclock -w

## 从BIOS时间写入系统
sudo hwclock -s

修改时区

## 列出所有时区
sudo timedatectl list-timezones

## 修改时区
sudo timedatectl set-timezone Asia/Shanghai

在Linux访问windows

rdesktop -u USER -p PASSWD IP

Windows下 要先开启远程桌面访问权限

CPU & GPU

CPU

物理CPU个数

grep "physical id" /proc/cpuinfo | sort| uniq| wc -l

每个物理CPU的核数

cat /proc/cpuinfo| grep "cpu cores" | uniq

线程个数

cat /proc/cpuinfo| grep "processor"| wc -l

是否启动超线程

cat /proc/cpuinfo | grep -e "cpu cores"  -e "siblings" | sort | uniq

如果 cpu coressiblings 的数量一致就没有启动了超线程, 否则就启动了超线程

CPU型号

grep name /proc/cpuinfo | uniq

锁频

lock_freq_cpu_2000_gpu_700mhz

sudo echo 700 > /sys/kernel/debug/dri/0/i915_max_freq
#sleep 1
cat /sys/kernel/debug/dri/0/i915_max_freq
sudo echo 700 > /sys/kernel/debug/dri/0/i915_min_freq
#sleep 1
cat /sys/kernel/debug/dri/0/i915_min_freq


for((i=0;i<8;i++))
do
sudo echo 2000000 > /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_min_freq
#sleep 1
cat /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_min_freq
sudo echo 2000000 > /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_max_freq
#sleep 1
cat /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_max_freq
done
sleep 1
cat /proc/cpuinfo |grep MHz

内存

看内存物理信息

sudo dmidecode -t memory

内存使用

cat /proc/meminfo
free

从频率看DDR几

DDR1: 333MHZ和400MHZ DDR2: 533,667,800 DDR3: 1066,1333,1600,2133 DDR4: 2133,2400,3000,3333

Bash 快捷键

操作快捷键
移动光标至行首CTRL+A
第一次按时,移动光标至行首再次按时,回到原有位置CTRL+X
移动光标至行尾CTRL+E
光标向左移动一个字符CTRL+B
光标向左移动一个单词ESC+B
光标向右移动一个字符CTRL+F
光标向右移动一个单词ESC+F
删除光标前一个字符,即退格(Backspace)CTRL+H
删除光标前所有字符CTRL+U
删除光标后所有字符CTRL+K
删除光标前一个单词CTRL+W
删除光标后一个字符,(相当于Delete)无任何字符时相当于exitCTRL+D
粘贴之前(CTRL+U/K/W)删除的内容CTRL+Y
清屏,相当于指令 clearCTRL+L
查找并自动匹配之前使用过的指令CTRL+R
回车,相当于EnterCTRL+M
跳到新行,等同于回车CTRL+O
新起一行,命令行下等同于回车CTRL+J
横行制表符,在命令行中补齐指令, 效果和Tab键相同CTRL+ I
补齐指令TAB
上一条指令,等同于向上箭CTRL+P
下一条指令,等同于向下箭CTRL+N
中断操作CTRL+C
冻结终端操作(暂停脚本)CTRL+S
恢复冻结(继续执行脚本)CTRL+Q
使下一个单词首字母大写, 同时光标前进一个单词, 如光标停留在单词的某个字母上, 如word中的o字母上, 则o字母变大写. 而不是wESC+C
使下一个单词所有字母变大写, 同时光标前进一个单词; 如光标在o字母上, 则ord变大写, w不变.ESC+U
使下一个单词所有字母变小写, 同时光标前进一个单词; 如光标在o字母上, 则ord变小写, w不变.ESC+I
将光标处的字符和光标前一个字符替换位置CTRL+T
重复运行最近一条以“word”开头的指令,如!ls 或 !l!word
调用上一条指令的最后一个参数作为当前指令对象, 如,假设上一条指令为: ls abc.txt bbc.txt 那么, vi !$ 相当于: vi bbc.txt!$
调用执行指定编号的历史记录指令,如!2, !11!number

转载于:https://my.oschina.net/u/3845788/blog/1818614

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值