前端学习 linux - shell 编程 linux怎么进行前端开发
liuian 2024-12-16 14:47 81 浏览
shell 原意是“外壳”,与 kernel(内核)相对应,比喻内核外的一层,是用户和内核沟通的桥梁。shell 有很多种,国内通常使用 bash。
第一个 shell 脚本
创建 hello-world.sh 文件,内容如下:
test11@pjl:~/tmp$ vim hello-world.sh
#!/bin/bash
echo 'hello world'
第一行指定 shell 的类型:
test11@pjl:~/tmp$ echo $SHELL
/bin/bash
Tip:通常约定以 sh 结尾。提前剧透:
test11@pjl:~/tmp$ sh hello-world.xx
hello world
执行 sh 文件,提示权限不够:
test11@pjl:~/tmp$ ./hello-world.sh
-bash: ./hello-world.sh: 权限不够
test11@pjl:~/tmp$ ll
-rw-rw-r-- 1 test11 test11 31 6月 17 16:18 hello-world.sh
增加可执行权限:
test11@pjl:~/tmp$ chmod u+x hello-world.sh
test11@pjl:~/tmp$ ll
# hello-world.sh 变绿了
-rwxrw-r-- 1 test11 test11 31 6月 17 16:18 hello-world.sh*
使用相对路径方式再次执行即可:
test11@pjl:~/tmp$ ./hello-world.sh
hello world
也可以使用绝对路径执行:
test11@pjl:~/tmp$ /home/test11/tmp/hello-world.sh
hello world
通过 sh xx.sh 无需可执行权限也可以执行。
Tip:下文还会使用 bash xx.sh 的执行方式。
首先删除可执行权限:
test11@pjl:~/tmp$ chmod u-x hello-world.sh
test11@pjl:~/tmp$ ll
总用量 20
-rw-rw-r-- 1 test11 test11 31 6月 17 16:18 hello-world.sh
test11@pjl:~/tmp$ sh hello-world.sh
hello world
shell 注释
- 单行注释:# 内容
- 多行注释:
:<<!
内容1
内容2
...
内容N
!
变量
系统变量
例如 $SHELL 就是系统变量:
test11@pjl:~/tmp$ echo $SHELL
/bin/bash
可以通过 set 查看系统变量。例如过滤 SHELL 系统变量:
test11@pjl:~/tmp$ set |more |grep SHELL
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
自定义变量
定义变量age并输出:
test11@pjl:~/tmp$ vim demo.sh
test11@pjl:~/tmp$ sh demo.sh
age=18
age=18
内容如下:
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
age=18
echo age=$age
echo "age=$age"
注:1. 定义变量不要在等号前后加空格;2. 使用变量要使用 $;3. 最后两行输出效果相同
# `age=18` 改为 `age= 18`
test11@pjl:~/tmp$ sh demo.sh
demo.sh: 2: 18: not found
age=
age=
使用 unset 可以销毁变量。请看示例:
test11@pjl:~/tmp$ vim demo.sh
test11@pjl:~/tmp$ sh demo.sh
age=18
age=
# 脚本内容
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
age=18
echo age=$age
unset age
echo age=$age
注:销毁变量 age 后再使用该变量,没有报错。
通过 readonly 定义静态变量,不能 unset。请看示例:
test11@pjl:~/tmp$ vim demo.sh
test11@pjl:~/tmp$ sh demo.sh
age=18
demo.sh: 4: unset: age: is read only
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
readonly age=18
echo age=$age
unset age
变量定义规则:
- 字母数字下划线,不能以数字开头
- 等号两侧不能有空格
- 变量名习惯大写
可以将命令运行结果赋予变量。请看示例:
命令 date:
test11@pjl:~/tmp$ date
2022年 06月 17日 星期五 16:52:57 CST
test11@pjl:~/tmp$ vim demo.sh
test11@pjl:~/tmp$ sh demo.sh
date1=2022年 06月 17日 星期五 16:54:02 CST
date2=2022年 06月 17日 星期五 16:54:02 CST
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
date1=`date`
date2=$(date)
echo date1=$date1
echo date2=$date2
环境变量
比如我在多个 .sh 文件中需要使用一个公共的变量,这时就可以使用环境变量,或称之为全局变量。
环境变量通过 export=value 定义在 /etc/profile 文件中。请看第 30 行:
test11@pjl:~$ cat -n /etc/profile
1 # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
2 # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
3
4 if [ "${PS1-}" ]; then
5 if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
6 # The file bash.bashrc already sets the default PS1.
7 # PS1='\h:\w\$ '
8 if [ -f /etc/bash.bashrc ]; then
9 . /etc/bash.bashrc
10 fi
11 else
12 if [ "`id -u`" -eq 0 ]; then
13 PS1='# '
14 else
15 PS1='$ '
16 fi
17 fi
18 fi
19
20 if [ -d /etc/profile.d ]; then
21 for i in /etc/profile.d/*.sh; do
22 if [ -r $i ]; then
23 . $i
24 fi
25 done
26 unset i
27 fi
28
29
30 export ANDROID_HOME=/home/pjl/software/android-studio-2021.1.1.22-linux/android-studio/bin
31 export PATH=$PATH:$ANDROID_HOME
这里定义了一个环境变量 ANDROID_HOME,将其输出看一下:
test11@pjl:~$ echo $ANDROID_HOME
/home/pjl/software/android-studio-2021.1.1.22-linux/android-studio/bin
现在我们定义一个环境变量 EVN-VAR-TEST=pjl:
# 查看文件最后两行
root@pjl:/home/test11# tail -2 /etc/profile
export PATH=$PATH:$ANDROID_HOME
export EVN_VAR_TEST=pjl
新的环境变量需要执行 source 才能立即生效。请看实例:
# 新的环境变量未生效
root@pjl:/home/test11# echo $EVN_VAR_TEST
# 修改后的配置信息立即生效
root@pjl:/home/test11# source /etc/profile
# 新的环境变量已生效
root@pjl:/home/test11# echo $EVN_VAR_TEST
pjl
尝试在 demo.sh 中使用新增环境变量。请看示例:
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
:<<!
date1=`date`
date2=$(date)
echo date1=$date1
echo date2=$date2
!
echo env_var_test=$EVN_VAR_TEST
运行 demo.sh,发现变量为空,让配置立即生效即可:
test11@pjl:~/tmp$ sh demo.sh
env_var_test=
test11@pjl:~/tmp$ echo $EVN_VAR_TEST
test11@pjl:~/tmp$ source /etc/profile
test11@pjl:~/tmp$ echo $EVN_VAR_TEST
pjl
test11@pjl:~/tmp$ sh demo.sh
env_var_test=pjl
注:笔者以 root 用户新增环境变量,并让配置生效,接着切换到 test11 用户,需要再次让配置生效。
位置参数变量
请先看示例:
test11@pjl:~/tmp$ sh demo.sh 100 200
demo.sh 100 200
100 200
100 200
2
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
echo $0 $1 $2
echo $*
echo $@
echo $#
语法介绍:
- $0 - 命令本身
- $1 - 第一个参数。第10个参数需要写成 ${10}
- $* - 命令行中所有参数。所有参数看做一个整体
- $@ - 命令行中所有参数。把每个参数区分对待
- $# - 参数个数
预定义变量
shell设计者预先定义变量,可以在 shell 脚本中直接使用。
Tip:用得不多,仅做了解。
语法介绍:
$ - 当前进程的进程号
$! - 后台运行的最后一个进程的进程号
$? - 最后一次执行的命名的返回状态。0 表示执行成功。
请看示例:
test11@pjl:~/tmp$ sh demo.sh
29174
test11@pjl:~/tmp$ cat demo.sh
#!/bin/bash
echo $
运算符
请看示例:
test11@pjl:~/tmp$ ./demo.sh 1 8
v1=18
v2=18
v3=18
v4=9
test11@pjl:~/tmp$ cat -n demo.sh
1 #!/bin/bash
2 v1=$(((1+8)*2))
3 echo v1=$v1
4 # 推荐
5 v2=$[(1+8)*2]
6 echo v2=$v2
7
8 tmp=`expr 1 + 8`
9 v3=`expr $tmp \* 2`
10 echo v3=$v3
11
12 v4=$[$1+$2]
13 echo v4=$v4
语法介绍:
- 有三种运算的方式:$((运算符))、$[运算式]、expr a + b。推荐使用 $[]
- expr 运算符需要有空格,例如 expr 1+8 就没有空格,而且乘号需要加一个转义符 \*
Syntax error: "(" unexpected
test11@pjl:~/tmp$ sh demo2.sh
demo2.sh: 2: Syntax error: "(" unexpected
test11@pjl:~/tmp$ cat -n demo2.sh
1 #!/bin/bash
2 v1=$[(1+8)*2]
3 echo v1=$v1
据网友介绍:ubuntu 上 sh 命令默认是指向 dash,而不是 bash。dash 比 bash 更轻量,只支持基本的 shell 功能,有些语法不识别。可以直接用 bash a.sh,或者./a.sh 来执行脚本。
改为 bash 或 ./ 的方式执行,确实可以。请看示例:
test11@pjl:~/tmp$ bash demo2.sh
v1=18
if
语法有点怪,先看示例:
test11@pjl:~/tmp$ sh demo2.sh
abc 等于 abc
100 大于等于 99
存在 /home/test11/tmp/demo2.sh
test11@pjl:~/tmp$ cat -n demo2.sh
1 #!/bin/bash
2 if [ 'abc'='abc' ]
3 then
4 echo 'abc 等于 abc'
5 fi
6
7 if [ 100 -ge 99 ]
8 then
9 echo '100 大于等于 99'
10 fi
11
12 if [ -f /home/test11/tmp/demo2.sh ]
13 then
14 echo '存在 /home/test11/tmp/demo2.sh'
15 fi
语法介绍:
- if 判断使用 [ 条件 ] 语法,[] 前后要有空格
- 字符串比较用 =。非空返回 true
- 数字比较:-lt 小于、-le 小于等于、-eq 等于、-gt 大于、-ge 大于等于、-ne 不等于
- 文件权限进行判断:-r 有读的权限、-w 有写的权限、-e 有执行的权限
- 文件类型进行判断:-f 文件存在且是一个常规文件、-e 文件存在、-d 文件存在并是一个目录
注:[] 前后要有空格,否则会报错。请看示例:
test11@pjl:~/tmp$ sh demo2.sh
demo2.sh: 2: []: not found
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
if []
then
echo '空字符'
fi
增加一个空格,由于空字符是假值,所以不会有输出:
test11@pjl:~/tmp$ sh demo2.sh
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
if [ ]
then
echo '空字符'
fi
elseif
请看示例:
test11@pjl:~/tmp$ sh demo2.sh dog
狗,100块
test11@pjl:~/tmp$ sh demo2.sh cat
猫,102块
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
# echo 参数1=$1
if [ $1 = "dog" ]
then
echo '狗,100块'
elif [ $1 = "cat" ]
then
echo '猫,102块'
fi
类似前端的 if...elseif...elseif。
case
请看示例,如果传参是 dog ,输出 '狗':
test11@pjl:~/tmp$ sh demo2.sh dog
狗
test11@pjl:~/tmp$ sh demo2.sh cat
猫
test11@pjl:~/tmp$ sh demo2.sh xx
其他动物
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
case $1 in
"dog")
echo '狗'
;;
"cat")
echo '猫'
;;
*)
echo '其他动物'
;;
esac
语法介绍:
case $变量名 in
"值1")
变量的值等于“值1”,执行程序1
;;
"值2")
变量的值等于“值2”,执行程序2
;;
*)
都不满足,执行
;;
esac
循环
for
// 具体的几个值
for i in v1 v2 v3 ...
do
程序
done
以下示例演示了 $@ 和 $* 的区别:
test11@pjl:~/tmp$ sh demo2.sh a b c
num1=a
num1=b
num1=c
num2=a b c
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
for i in "$@"
do
echo num1=$i
done
for i in "$*"
do
echo num2=$i
done
你有几个参数,$@ 就把你当做几个;$* 只会把你当做一个整体;
语法二
for (( 初始值;循环控制条件;变量变化))
do
程序
done
请看示例:
test11@pjl:~/tmp$ bash demo2.sh 100
1 到 100 的和:5050
test11@pjl:~/tmp$ cat -n demo2.sh
1 #!/bin/bash
2
3 sum=0
4 for(( i=1; i <= $1; i++))
5 do
6 sum=$[$sum+$i]
7 done
8 echo 1 到 $1 的和:$sum
注:第6行不要写成 $sum=$[$sum+$i]
while
请看示例:
test11@pjl:~/tmp$ bash demo2.sh 100
1 到 100 的和:5050
test11@pjl:~/tmp$ cat -n demo2.sh
1 #!/bin/bash
2
3 sum=0
4 i=1
5
6 # while [ $i <= $1 ]
7 while [ $i -le $1 ]
8 do
9 sum=$[$sum+$i]
10 i=$[$i+1]
11 done
12
13 echo 1 到 $1 的和:$sum
假如把第 6 行放开,报错如下:
test11@pjl:~/tmp$ bash demo2.sh 100
demo2.sh: 行 6: =: 没有那个文件或目录
1 到 100 的和:0
语法介绍:
while [ 条件判断 ]
do
程序
done
Tip:while 和 [ 之间有空格;条件判断与 ] 有空格。例如删除一个空格就会报错 while[ $i -le $1 ]:
test11@pjl:~/tmp$ bash demo2.sh 100
demo2.sh: 行 6: while[ 1 -le 100 ]:未找到命令
demo2.sh: 行 7: 未预期的符号“do”附近有语法错误
demo2.sh: 行 7: `do'
read 获取控制台输入
test11@pjl:~/tmp$ sh demo2.sh
请输入你个名字:
程序会阻塞,当你输入后会继续执行:
test11@pjl:~/tmp$ sh demo2.sh
请输入你个名字:pjl
name=pjl
通过 -t 参数能指定等待时间(秒),例如 5 秒内如果没有输入,程序会继续执行:
test11@pjl:~/tmp$ bash demo2.sh
请输入你个名字:name=
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
read -t 5 -p 请输入你个名字: name
语法:read 选项 参数。
test11@pjl:~/tmp$ read -h
-bash: read: -h:无效选项
read:用法: read [-ers] [-a 数组] [-d 分隔符] [-i 缓冲区文字] [-n 读取字符数] [-N 读取字符数] [-p 提示符] [-t 超时] [-u 文件描述符] [名称 ...]
test11@pjl:~/tmp$ read --help
read: read [-ers] [-a 数组] [-d 分隔符] [-i 缓冲区文字] [-n 读取字符数] [-N 读取字符数] [-p 提示符] [-t 超时] [-u 文件描述符] [名称 ...]
从标准输入读取一行并将其分为不同的域。
从标准输入读取单独的一行,或者如果使用了 -u 选项,从文件描述符 FD 中读取。
该行被分割成域,如同词语分割一样,并且第一个词被赋值给第一个 NAME 变量,第二
个词被赋值给第二个 NAME 变量,如此继续,直到剩下所有的词被赋值给最后一个 NAME
变量。只有 $IFS 变量中的字符被认作是词语分隔符。
如果没有提供 NAME 变量,则读取的行被存放在 REPLY 变量中。
选项:
-a array 将词语赋值给 ARRAY 数组变量的序列下标成员,从零开始
-d delim 持续读取直到读入 DELIM 变量中的第一个字符,而不是换行符
-e 使用 Readline 获取行
-i text 使用 TEXT 文本作为 Readline 的初始文字
-n nchars 读取 nchars 个字符之后返回,而不是等到读取换行符。
但是分隔符仍然有效,如果遇到分隔符之前读取了不足 nchars 个字符。
-N nchars 在准确读取了 nchars 个字符之后返回,除非遇到文件结束符或者读超时,
任何的分隔符都被忽略
-p prompt 在尝试读取之前输出 PROMPT 提示符并且不带
换行符
-r 不允许反斜杠转义任何字符
-s 不回显终端的任何输入
-t timeout 如果在 TIMEOUT 秒内没有读取一个完整的行则超时并且返回失败。
TMOUT 变量的值是默认的超时时间。TIMEOUT 可以是小数。
如果 TIMEOUT 是 0,那么仅当在指定的文件描述符上输入有效的时候,
read 才返回成功;否则它将立刻返回而不尝试读取任何数据。
如果超过了超时时间,则返回状态码大于 128
-u fd 从文件描述符 FD 中读取,而不是标准输入
退出状态:
返回码为零,除非遇到了文件结束符、读超时(且返回码不大于128)、
出现了变量赋值错误或者无效的文件描述符作为参数传递给了 -u 选项。
函数
请看示例:
test11@pjl:~/tmp$ bash demo2.sh
sum=300
test11@pjl:~/tmp$ cat demo2.sh
#!/bin/bash
# 定义函数
function sum() {
# 第一个参数为 $1
sum=$[$1+$2]
echo sum=$sum
}
# 执行函数
sum 100 200
语法介绍:
[ function ] funname [()]
{
action;
[return int;]
}
系统函数
shell 中也有系统函数。我们介绍两个抛砖引玉一下:
- basename,返回文件名
- dirname,返回路径
test11@pjl:~/tmp$ basename /a/b/c/a.txt
a.txt
test11@pjl:~/tmp$ basename /a/b/c/a.txt .txt
a
test11@pjl:~/tmp$ dirname /a/b/c/a.txt
/a/b/c
shell 综合练习
需求:每天凌晨 3 点备份数据库。
实现如下:
假如 test.txt 就是我们备份完成的数据库:
root@pjl:/home/test11/tmp# ls
backup_database.sh test.txt
执行三次写好的备份数据库的脚本:
root@pjl:/home/test11/tmp# bash backup_database.sh
DATETIME=2022-06-21_200903
2022-06-21_200903/
2022-06-21_200903/2022-06-21_200903.txt.gz
root@pjl:/home/test11/tmp# bash backup_database.sh
DATETIME=2022-06-21_200904
2022-06-21_200904/
2022-06-21_200904/2022-06-21_200904.txt.gz
root@pjl:/home/test11/tmp# bash backup_database.sh
DATETIME=2022-06-21_200905
2022-06-21_200905/
2022-06-21_200905/2022-06-21_200905.txt.gz
我们需要将数据备份到 /data/backup/db/ 目录中,现已生成3个备份:
root@pjl:/home/test11/tmp# ls /data/backup/db/
2022-06-21_200903.tar.gz 2022-06-21_200904.tar.gz 2022-06-21_200905.tar.gz
最后看一下备份脚本内容:
root@pjl:/home/test11/tmp# cat -n backup_database.sh
1 #!/bin/bash
2
3 # 将数据备份到这 db 目录
4 BACKDIR=/data/backup/db
5
6 # 当前时间
7 # 输出:DATETIME=2022-06-21_110318
8 DATETIME=$(date +%Y-%m-%d_%H%M%S)
9 echo DATETIME=$DATETIME
10
11 # 创建备份目录。如果不存在,则创建
12 [ ! -d "${BACKDIR}/${DATETIME}" ] && mkdir -p "${BACKDIR}/${DATETIME}"
13
14 # 备份数据。读取 text.txt 传给 gzip 压缩,在重定向到指定目录
15 cat test.txt | gzip > ${BACKDIR}/${DATETIME}/$DATETIME.txt.gz
16
17 # 将文件处理成 tar.gz
18 cd ${BACKDIR}
19 tar -zcvf $DATETIME.tar.gz ${DATETIME}
20
21 # 删除对应的备份目录
22 rm -rf ${BACKDIR}/${DATETIME}
Tip:${}通常用于划定变量名的边界,例如:
test11@pjl:~$ a=1
test11@pjl:~$ aa=2
test11@pjl:~$ echo $aa
2
test11@pjl:~$ echo ${a}a
1a
test11@pjl:~$ echo "${a}a"
1a
相关推荐
- eino v0.4.5版本深度解析:接口类型处理优化与错误机制全面升级
-
近日,eino框架发布了v0.4.5版本,该版本在错误处理、类型安全、流处理机制以及代理配置注释等方面进行了多项优化与修复。本次更新共包含6个提交,涉及10个文件的修改,由2位贡献者共同完成。本文将详...
- SpringBoot异常处理_springboot异常注解
-
在SpringBoot中,异常处理是构建健壮、可维护Web应用的关键部分。良好的异常处理机制可以统一返回格式、提升用户体验、便于调试和监控。以下是SpringBoot中处理异常的完整指...
- Jenkins运维之路(Jenkins流水线改造Day02-1-容器项目)
-
这回对线上容器服务器的流水线进行了一定的改造来满足目前线上的需求,还是会将所有的自动化脚本都放置到代码库中统一管理,我感觉一章不一定写的完,所以先给标题加了个-1,话不多说开干1.本次流水线的流程设计...
- 告别宕机!零基础搭建服务器监控告警系统!小白也能学会!
-
前言本文将带你从零开始,一步步搭建一个完整的服务器指标监控与邮件告警系统,使用的技术栈均为业界主流、稳定可靠的开源工具:Prometheus:云原生时代的监控王者,擅长指标采集与告警规则定义Node_...
- httprunner实战接口测试笔记,拿走不谢
-
每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试码同学抖音号:小码哥聊软件测试01开始安装跟创建项目pipinstallhttprunne...
- 基于JMeter的性能压测平台实现_jmeter压测方案
-
这篇文章已经是两年前写的,短短两年时间,JMeter开源应用技术的发展已经是翻天覆地,最初由github开源项目zyanycall/stressTestPlatform形成的这款测试工具也开始慢...
- 12K+ Star!新一代的开源持续测试工具!
-
大家好,我是Java陈序员。在企业软件研发的持续交付流程中,测试环节往往是影响效率的关键瓶颈,用例管理混乱、接口调试复杂、团队协作不畅、与DevOps流程脱节等问题都能影响软件交付。今天,给大家...
- Spring Boot3 中分库分表之后如何合并查询
-
在当今互联网应用飞速发展的时代,数据量呈爆发式增长。对于互联网软件开发人员而言,如何高效管理和查询海量数据成为了一项关键挑战。分库分表技术应运而生,它能有效缓解单库单表数据量过大带来的性能瓶颈。而在...
- 离线在docker镜像方式部署ragflow0.17.2
-
经常项目上会出现不能连外网的情况,要怎么使用ragflow镜像部署呢,这里提供详细的步骤。1、下载基础镜像根据docker-compose-base.yml及docker-compose.yml中的i...
- 看,教你手写一个最简单的SpringBoot Starter
-
何为Starter?想必大家都使用过SpringBoot,在SpringBoot项目中,使用最多的无非就是各种各样的Starter了。那何为Starter呢?你可以理解为一个可拔插式...
- 《群星stellaris》军事基地跳出怎么办?解决方法一览
-
《群星stellaris》军事基地跳出情况有些小伙伴出现过这种情况,究竟该怎么解决呢?玩家“gmjdadk”分享的自己的解决方法,看看能不能解决。我用英文原版、德语、法语和俄语四个版本对比了一下,结果...
- 数据开发工具dbt手拉手教程-03.定义数据源模型
-
本章节介绍在dbt项目中,如何定义数据源模型。定义并引入数据源通过Extract和Load方式加载到仓库中的数据,可以使用dbt中的sources组件进行定义和描述。通过在dbt中将这些数据集(表)声...
- docker compose 常用命令手册_docker-compose init
-
以下是DockerCompose常用命令手册,按生命周期管理、服务运维、构建配置、扩缩容、调试工具分类,附带参数解析、示例和关键说明,覆盖多容器编排核心场景:一、生命周期管理(核心命令...
- RagFlow与DeepSeek R1本地知识库搭建详细步骤及代码实现
-
一、环境准备硬件要求独立显卡(建议NVIDIAGPU,8GB显存以上)内存16GB以上,推荐32GB(处理大规模文档时更高效)SSD硬盘(加速文档解析与检索)软件安装bash#必装组件Docker...
- Docker Compose 配置更新指南_docker-compose配置
-
高效管理容器配置变更的最佳实践方法重启范围保留数据卷适用场景docker-composeup-d变更的服务常规配置更新--force-recreate指定/所有服务强制重建down→up流程...
- 一周热门
-
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
飞牛OS入门安装遇到问题,如何解决?
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)