最近想开一个新坑,每日学习一条Linux命令。有兴趣的大家可以一起来学撒。推荐大家购买自己的一台小的服务器,这样每次学习能看到效果也是十分有成就感滴!
免密登录(11/19)
1.先用ssh登录自己的服务器
但是笔者之前已经配置过免密登录了,但是我又重置了服务器密码。所以就报了这个错误。
根据提示,我们把本地的.ssh文件夹下的know_hosts里面相关的信息删除就好了。
欧克,我们现在正常登录上去了。接下来可以配置免密登录了。
2.配置免密登录
配置免密登录我们需要修改几个配置文件,在我们的本地中修改ssh
下面的config
文件
vim ~/.ssh/config
修改config文件
Host 自己起的别名
HostName ip地址
User 用户名
Port 端口号
我们再来ssh登录一下。说明我们配置成功了,但是还没有免密登录。
接下来就是配置免密登录了,就可以不用输入密码了!!!
方式一:将本地的Public-key复制到服务器里面。
cat ~/.ssh/id_rsa.pub
在vim编辑器里面,我们可以使用ctrl + ins
和shift + ins
实现复制粘贴。如果本地没有 ~/.ssh/id_rsa.pub
,可以使用ssh-keygen
生成一个。
进入服务器,编辑
authorized_keys
文件,把公钥全部复制进去即可。
vim ~/.ssh/authorized_keys
现在,我们直接ssh登录我们自己起的别名就可以了
方式二 ssh-copy-id
ssh-copy-id [服务器别名]
这个命令就可以直接将本地的公钥上传到你的服务器里面,是不是很方便。
方式三
cat ~/.ssh/id_rsa.pub | ssh user@ip "cat >> ~/.ssh/authorized_keys"
附上链接:gist.github.com/nickbayley/…
小白也还没有看懂,就不解释了。
欧克,今天的任务到此就结束啦。
ssh隧道(11/20)
ssh -NL
当我们在宿主机(个人的 mac、windows 等笔记本)本地进行开发时,只需要在浏览器打开 localhost,便可以愉快地进行开发。
当我们在远程服务器中对某一 web 服务进行开发并测试时,我们很难在宿主机本地进行调试。
我们无法在宿主机中访问服务器中的服务。但,此时可借助于 ssh 隧道,将服务器端口号映射到宿主机本地,则可以愉快地将服务器作为开发环境了。
将远程服务器的端口号可在本地进行访问。
以下命令将远程服务器中的 localhost:5000 映射到本地的 5000 端口,在浏览器中可直接输入 localhost:5000 进行开发调试。
# 在远程服务器开启一个 5000 端口号的服务,此时需要 node 环境
root$ npx serve . -p 5000
在我们本地上面,进行如下操作
# 将远程服务器的 5000 端口供本地使用,此时窗口会被占用
# -N: 用以端口转发
# -L: 将服务器中 localhost:5000 映射到本地 5000 端口
local$ ssh -NL 5000:localhost:5000 root(服务器别名)
# 此时需要另开一个窗口,用以执行命令
local$ curl localhost:5000
笔者用的是腾讯云的轻量应用服务器,是没有安全组的,然后我开放了5000这个端口。按理来说安全组放开就可以了,而且这是通过 ssh 隧道连接的,其实不放开 5000 端口号也是没问题的。
但是这里好像直接寄了
emm我这个端口应该是启动启来的,是没有问题的
换了一个端口尝试还是一样的问题,哎还没有找到解决的方案?
哎!终于知道了,5000:localhost:5000
是连在一起的,中间没有空格符,我太难了
欧克,现在我们可以在本地调试我们服务器上的端口了,在浏览器中输入localhost:5000
。但是我这里是拒绝访问。这又是啥问题呢?
哎,折腾了一会发现其实是没有问题的。这里特别感谢山月老师掘金账号帮我远程调调试。其实有些时候我们再复现一遍问题,或许问题自然而然就会解决了。
其实刚刚之所以会拒绝访问,是因为我的那个窗口挂掉了。所以直接访问不起了!
我们再来重新试一遍
成功!
后面我们可以用tmux将这个窗口挂起,就不会出现这种问题了。
ssh -NR
上述我们是在本地访问服务器端口,现在我们配置一下服务器访问本地的端口
我们在将本地的5000
端口映射到远程服务器的5000
端口
npx serve . -p 5000
ssh -NR 5000:localhost:5000 root
服务器
curl localhost:5000
大功告成!!!
rsync(11/21)
快速高效,支持断点续传、按需复制的文件拷贝工具,并支持远程服务器拷贝。
强烈建议在本地也使用 rsync
替换 cp
进行文件拷贝。
如果是windows电脑的话,需要配置一下rsync这个指令
远程复制
拷贝数据,习惯使用 -lahzv
结合命令。
如果需要拷贝至远程服务器,则以远程服务器名开头即可。
# 将本地的 react 拷贝到 shanyue 服务器的 ~/Documents 目录
# -l:--links,拷贝符号链接
# -a:--archive,归档模式
# -h:--human-readable,可读化格式进行输出
# -z:--compress,压缩传输
# -v:--verbose,详细输出
# chenyyy: 我的远程服务器
$ rsync -lahzv ~/Documents/react shanyue:/home/shanyue/Documents
另一边可以接受到
归档模式(11/22)
rsync
归档模式最大的好处是可以拷贝元属性,如 ctime/mtime/mode 等等,这对于静态资源服务器相当有用!!!
什么是属性和原属性?
资源具有属性。每个属性都具有名称、类型和值;它们可能还具有与其相关联的其他元属性(例如:值、大小或有效性指示)。
# 查看其 data.txt 信息
$ ls -lah | grep data.txt
-rw-r--r-- 1 root root 0 Nov 21 04:53 data.txt
# data.txt 使用 rsync 拷贝
$ rsync -lahz data.txt data1.txt
# data.txt 使用 cp 拷贝
$ cp data.txt data2.txt
# 观察可知
# rsync 修改时间/mode 与源文件保持一致
# cp 修改时间为当前最新时间,mode 也不一致
-rw-r--r-- 1 root root 0 Nov 21 04:53 data.txt
-rw-r--r-- 1 cwl cwl 0 Nov 21 04:53 data1.txt
-rw-r--r-- 1 cwl cwl 0 Nov 21 23:24 data2.txt
拷贝目录
拷贝目录,则需要看原目录
是否以 / 结尾。
- 不以 / 结尾,代表将该目录连同目录名一起进行拷贝
- 以 / 结尾,代表将该目录下所有内容进行拷贝
# 这两个效果一样的
rsync -lahz program/ program1
rsync -lahz program/ program2/
rsync -lahz program program5
rsync -lahz program program6/
是否拷贝目录,主要是看原目录
是否以/
结尾
思考题:
1.在使用 rsync 传输前端项目时,如何忽略 node_modules 目录
rsync --exclude node_modules
2.如何在nodejs中实现cp命令
3.为何说保留复制文件时的元属性,对静态资源服务器有益
第一次传输
我尝试了 rsync 重复复制同一个文件到服务器, 发现只有第一次是实际上传的, 后续几次都是只有简单的一些信息,数据传输量不大。这一块的传输优化, 是不是就是基于文件的元属性,比如 ctime mtime 这些来的呢? 以及是像昨天晚上说的 etag 这种文件新鲜度计算的方式么?(留个疑问)
目录和切换操作(11/23)
cd
cd
,change directory
,切换当前工作目录。
除指定目录外,还有以下特殊目录。
.
: 当前工作目录。..
: 父级工作目录。/
: 根目录。~
: home 目录,即当前的用户目录,同时也可用环境变量$HOME
表示。
另外,cd -
为进入上一次的工作目录,如同 git checout -
切回上次的分支一样。
pwd
pwd
,print working directory
,打印当前工作目录。
ls
ls,列出某个工作目录的内容。
ls 单指令不会列出以 . 开头的文件,比如 .git、 .babelrc、.eslintrc 均不会默认显示。
而使用 -a,将会把所有文件列出。
在日常中,常使用 ls -lah 列出工作目录内容。
-l: 使用长列表格式
-a: 列出所有文件,包括以 . 开头的文件
-h: 以可读的形式表示文件体积,比如 100M
tree
tree
,以树状图的形式列出文件。
# -a列出所有文件
# 显示指定层级
tree -L n
使用 tree/exa 列出目录树时,如何忽略 .gitignore 中文件内容
tree -I "node_modules"
用户相关(11/24日)
whoami
# 打印当前的用户名
whoami
id
打印当前用户 ID 及用户组 ID。
在 Linux 中 root 用户为 0,第一个用户 id 默认为 1000
# -u: --user,打印 userId
# -n: --name,``打印 userId 所对应的用户名
$ id -un
who
打印出当前有哪些用户在登录状态。
# -u: 打印出登录用户的 IDLE/PID。
# -H: 打印标头,显示标题栏信息
$ who -uH
time
表示登录的时间,IDLE
表示活跃的时间,.
表示当前正在活跃
w
一个比 who -uH
更好用的,可查看有几人登录的工具。
last
打印出该服务器的历史登录用户。
# 打印最近10批
last -n 10
作业
- 如何打印某一天的服务器上有多少个登录用户
last -s 2022-7-13 -t 2022-7-14
- 如何打印你自己服务器的user id 及user name
id / whoami
chmod/chown(11/25)
chown
chown
,change owner。更改文件的所属用户及组。
通过 ls
命令,第三第四列便是文件所属用户及用户组。
更改权限到
ubuntu组
chmod
chmod
,change mode。更改文件的读写权限。
mode 指 linux 中对某个文件的访问权限。
通过 stat 可获取某个文件的 mode。
# -c:--format
# %a:获得数字的 mode
$ stat -c %a ubun.txt
644
$ stat -c %A ubun.txt
-rw-r--r--
在了解 mode 之前,我们先看一下文件的权限。
- r: 可读,二进制为 100,也就是 4
- w: 可写,二进制为 010,也就是 2
- x: 可执行,二进制为 001,也就是 1
而 linux 为多用户系统,我们可对用户进行以下分类。
- user。文件当前用户
- group。文件当前用户所属组
- other。其它用户
再回到刚才的 644
所代表的的释义
# rw-:当前用户可写可读,110`,即十进制 6
# r--:当前用户组可读,10`0,即十进制 4
# r--:其它用户可读,10`0,即十进制 4
# 所以加起来就是 644`
-rw-r--r--
另外也可以以可读化形式添加权限,如下所示:
# u: user
# g: group
# o: other
# a: all
# +-=: 增加减少复制
# perms: 权限
$ chmod [ugoa...][[+-=][perms...]...]
# 为 yarn.lock 文件的用户所有者添加可读权限
$ chmod u+r yarn.lock
# 为所有用户添加 yarn.lock 的可读权限
$ chmod a+r yarn.lock
# 为所有用户删除 yarn.lock 的可读权限
$ chmod a-r yarn.lock
当我们新建了一个文件时,他默认的 mode 是多少
普通用户:664
root用户:644
664 = -rw-rw-r--
644 = -rw-r--r--
link(11/26)
hard link(硬链接)
ln
,在两个文件间创建链接,默认为硬链接。
# 创建一个硬链接
$ ln ubun.txt ubunln.txt
查看ubun.txt
和ubunln.txt
的文件属性,发现都是一样的,确定是硬链接
在 stat
命令中,可发现硬链接文件与源文件
其 Links 变成了 2,Links 代表硬链接的个数。
具有相同的 Inode:657204
具有相同的 Size 及属性
symbol link(软链接)
ln -s
,在两个文件间创建符号链接,符号链接也被称为软链接。
cat/head/tail(11/27)
cat
cat
,concatenate
缩写,concatenate and print files
连接文件并打印至标准输出(stdout)。
$ cat README.md
# 也可以打印控制字符,比如 Tab、换行等不可见字符
# -v: 打印 <Ctrl-X>
# -e: 打印换行
# -t: 打印 TAB
$ cat -vet README.md
# 打印行号
$ cat -n READEME.md
head
head
,读取文件或者标准输入的前 N 行或前 N 个字节。
# 输出文件前 10 行内容
$ head -10 README.md
# 与以上命令同义
$ head --lines 10 READEME.md
# 输出文件前 10 个字节
$ head -c 10 READEME.md
tail
tail
,读取文件或者标准输入的最后 N 行或最后 N 个字节。
# 输出文件后 10 行内容
$ tail -10 README.md
但是它与 head
最大不同的一点是:--follow
,简写为 -f
。它可以实时打印文件中最新内容。
在调试日志时非常有用:日志一行一行追加到文件中,而 tail -f
可以实时打印追加的内容。
$ tail -f log.json
# 如果为了做实验,可再打开一个窗口通过 >> 重定向追加内容至 log.json,具体查看下一章
$ echo test >> log.json
pipe|redirection(11/28)
pipe
|
构成了管道,它将前边命令的标准输出(stdout)作为下一个命令的标准输入(stdin)。
标准输出
可以理解成将数据打印到终端上面,标准输入
可以理解成在终端中输入
# 读取 package.json 内容,读取前十行,再读取最后三行
$ cat package.json | head -10 | tail -3
stdin/stdout
在上边提到标准输入(stdin)与标准输出(stdout),其实,stdin/stdout 就是特殊的文件描述符。
stdin
,fd = 0,直接从键盘中读取数据stdout
,fd = 1,直接将数据打印至终端stderr
,fd = 2,标准错误,直接将异常信息打印至终端
redirection
>
:将文件描述符或标准输出中内容写入文件>>
:将文件描述符或标准输出中内容追加入文件
# READEME.md 内容为 hello,这里的文件描述符就是标准输出
$ echo hello > README.md
# READEME.md 内容最后一行为 hello
$ echo hello >> README.md
heredoc
在许多官方文档中的命令中,我们经常可以看到以下用法
$ cat <<EOF > READEME.md
...
其意思是将标准输入时的内容,写入到 README.md 中。
其中 <<EOF
,称作 Here Document
,当最终写入 EOF(End of file)时,则 heredoc 会停止输入。
日志重定向
/dev/null 是一个空文件,对于所有的输入都统统吃下,化为乌有,有时,为了不显示日志,可将所有标准输出重定向至 /dev/null。
/dev/null在类Unix系统中是一个特殊的设备文件,它丢弃一切写入其中的数据,读取它则会立即得到一个EOF。 在程序员行话,尤其是Unix行话中,/dev/null被称为比特桶或者黑洞。可以理解成充当的是垃圾箱的功能。
但此时,stderr 仍然会打印至屏幕。如果后边跟一个 2>&1,表示将 stderr (fd 为2) 重定向至 &1 (fd===1 的文件,及 stdout),同标准输出一同重定向至 /dev/null,也就是标准输出日志与标准错误日志都不显示。
# 不显示 stdout 内容
$ echo hello > /dev/null
# 既不显示 stdout,也不显示 stderr
# 此时 hello 文件不存在,如果没有后边的 2>&1,仍然会有日志打印至屏幕,如果加上 2>&1,则 stderr 也不显示
$ cat hello > /dev/null 2>&1
glob(11/29)
glob,global
的简写,使用通配符来匹配大量文件。比如 rm *.js
就可以删除当前目录所有 js 文件。
glob
拥有以下基本语法
*
:匹配0个及以上字符?
:匹配1个字符[...]
:range,匹配方括号内任意字符**
:匹配0个及多个子目录(在 bash 下,需要开启 globstar 选项)
root@VM-16-6-ubuntu:~/data# ls -lah *[ubu]*.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubunln.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubun.txt
root@VM-16-6-ubuntu:~/data# ls -lah *.txt
lrwxrwxrwx 1 root root 8 Nov 26 10:00 datalns.txt -> data.txt
-rw-r--r-- 1 root root 0 Nov 21 12:53 data.txt
-rw-r--r-- 1 lighthouse lighthouse 68 Nov 28 10:30 try1.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubunln.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubun.txt
brace
brace
,用以扩展集合、数组等,有以下语法。
set
:{a,b,c}
range
:{1..10}
,{01..10}
step
:{1..10..2}
$ echo {a,b,c}
a b c
# range: 输出 01 到 10
$ echo {01..10}
01 02 03 04 05 06 07 08 09 10
# step: 输出 1 到 10,但是每一步需要自增 2
$ echo {1..10..2}
1 3 5 7 9
# step: 输出 1 到 10,但是每一步需要自增 3
$ echo {1..10..3}
1 4 7 10
# step: 输出 10 到 1,但是每一步需要自减 2
$ echo {10..1..2}
10 8 6 4 2
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
列出所有以json
txt
结尾的文件
root@VM-16-6-ubuntu:~/data# ls -lah *.{json,txt}
-rw-r--r-- 1 root root 0 Nov 29 09:29 data.json
lrwxrwxrwx 1 root root 8 Nov 26 10:00 datalns.txt -> data.txt
-rw-r--r-- 1 root root 0 Nov 21 12:53 data.txt
-rw-r--r-- 1 lighthouse lighthouse 68 Nov 28 10:30 try1.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubunln.txt
-rw-r--r-- 2 ubuntu ubuntu 0 Nov 25 20:38 ubun.txt
find(11/30)
在 find
中,用以验证某个文件是否匹配的条件称为 Test
,一般基于文件的属性进行查找,而文件的属性,可通过 stat
命令进行获得。
-name
:根据文件名查找,注意文件名需要使用引号括起来-mtime
:根据mtime
属性查找-perm
:根据权限进行查找-type
:根据文件类型进行查找-inum
:根据inode
属性查找,用以寻找硬链接非常有用
另外,对于某些数字属性,还有 +
/-
用以比较
+n
:大于 n,如find. -mtime +30
,递归遍历最近修改时间大于 30 天的文件-n
:小于 n,如find. -mtime -30
,递归遍历最近修改时间小于 30 天的文件
# 注意,如果文件路径名使用 glob,则需要使用引号括起来
$ find . -name '*.json'
# 在当前目录递归查找包含 hello 的文件
$ find . -name '*hello*'
# 在当前目录递归查找修改时间大于 30 天并且小于 60 天的文件
# 其中数字以天为单位,+ 表示大于,- 表示小于
# +30: 大于30天
# -60: 小于60天
$ find . -mtime +30 -mtime -60
# 在当前目录递归查找权限 mode 为 777 的文件
$ find . -perm 777
# 在当前目录递归查找类型为 f/d/s 的文件
$ find . -type f
$ find . -type d
$ find . -type s
# 在当前目录递归查找 inode 为 10086 的文件
# 一般用以寻找硬链接的个数,比如 pnpm 中某一个 package 的全局路径在哪里
$ find . -inum 10086
# 寻找相同的文件(硬链接),与以上命令相似
$ find . -samefile package.json
# 仅在当前目录递归检索
$ find . -mindepth 1 -maxdepth 1 -name '*.json'
ag(12/1)
根据文件内容进行搜索
$ ag hello
vim
模式
normal。普通模式,刚进入 vim 的默认模式,也是最重要的模式。 确保大部分操作在普通模式下完成,而不是插入模式。
insert。插入模式。在普通模式下通过 i 进入插入模式,在插入模式下进行文字编辑。
command。命令模式。在普通模式下通过 : 进入命令模式,在命令模式下执行命令。
insert mode commands
一般来说,通过 i
进入 insert mode
,但除此之外,还有一些更好用的进入插入模式的命令。
i
: 进入插入模式,并定位光标至当前字符之前I
: 进入插入模式,并定位光标至当前行首a
: 进入插入模式,并定位光标至当前字符之后A
: 进入插入模式,并定位光标至当前行尾o
: 进入插入模式,当前光标之后新建一行,并定位光标至后一行O
: 进入插入模式,当前光标之前新建一行,并定位光标至前一行
normal mode commands
一般来说,通过 <esc>
可退出 insert mode
,但是基于两方面考虑,一般不使用该键
<esc>
过于偏远,按键不方便。- 在 VSCode/Codepen/CodeSandbox 及命令行的 vi 模式下,
<esc>
可能与其它快捷键发生冲突。
可使用 <ctrl-c>
或者 <ctrl-[>
进行替代。
grep(12/3)
昨天考完了编译原理,摆烂了一会,今天继续学习一点。vim的操作单独写篇分享吧,关键是要多练习vim,才能熟练的操作它。
grep
只是一个正则的工具,具体还得靠你对正则的掌握程度。
- 找出和root有关的行,
-i
可以是忽略大小写,-c
可以统计出多少行和root
有关
grep "root" default
root$ grep "try" -i -c default
4
- 去除注释开头的行,
-v
表示方向匹配
grep '^#' default -v
- 去除注释并且去除空行,我们可以使用管道连接符
$ grep '^#' default -v | grep '^$' -v
- 去除以空格开头的注释行
$ grep -v "^\s*#"
wc(12/7)
艰难的期末周终于度过,又可以安安心心学习了。
wc
,word count
的缩写。用以统计文本中字符、单词及行数。
$ wc package.json
153 458 7432 package.json
# -l:--lines 行数
$ wc -l package.json
153 package.json
# 如果仅仅想显示行``数
$ cat package.json | wc -l
153
# -w:--words 词数
$ wc -w package.json
458 package.json
# -c:--bytes 字节数
$ wc -c package.json
7432 package.json
# -m:--chars 字符数
$ wc -m package.json
7432 package.json
tr
tr
,全局替换文件。tr
“从标准输入设备读取数据,经过字符串转译后,将结果输出到标准输出设备”,因为它并不能改变文件内容啊。
# 小写转化为大写
$ echo hello | tr a-z A-Z
HELLO
# hello -> world
$ echo hello | tr hello world
world
# 去除字符串中的多余空格
# -d:删除特定字符
$ echo " hello " | tr -d " "
sed(12/8)
sed
是一个用来筛选与转换文本内容的工具。一般用来批量替换,删除某行文件
sed命令详解
每个 sed 命令,基本可以由选项,匹配与对应的操作来完成
# 打印文件第三行到第五行
# -n: 选项,代表打印
# 3-5: 匹配,代表第三行到第五行
# p: 操作,代表打印
$ sed -n '3,5p' file
# 删除文件第二行
# -i: --in-place,选项,代表直接替换文件
# 2: 匹配,代表第二行
# d: 操作,代表删除
$ sed -i '2d' file
# -i可以直接修改文件,所以重要文件修改前我们需要备份一下
# 备份文件可以用cp,rsync等信息,也可也通过-i.bak 来备份文件,它会自动备份以bak结尾的文件
$ sed -i.bak '2d' a.txt
关键选项
-n: 仅显示处理之后的结果
-i: --in-place,原地替换文本内容
-f: --file,指定 sed 脚本文件,包含一系列 sed 命令
小练习(12/9)
- 过滤出含有 hello 字符串的行
# 我们可以通过之前学习的grep命令来过滤
$ grep hello a.txt
# 用sed命令,不过要稍微麻烦一点
$ ubuntu@ubuntu:~/sed$ sed -n '/hello/p' a.txt
hello
helloworld today
- 删除含有hello字符串的行,
ubuntu@ubuntu:~/sed$ sed -n '/hello/p' a.txt
hello
helloworld today
ubuntu@ubuntu:~/sed$ sed '/hello/d' a.txt
jsonp
cors
hhh
3.替换字符串
$ sed -i.bak 's#hello#HELLO#g' a.txt
dig(12/10)
解析某个域名的 IP 地址
dig www.bilibili.com
# 仅仅返回 IP 地址
$ dig +short www.bilibili.com
可以看出 b站 应该是做了负载均衡
12/30
终于过完了考试周,还有疫情的影响,已经断更好久了,接下来我们从学习shell开始吧!
shell
sh
sh,即 Shell Command Language
的简称,是由 Shell Command Language 表述的一份规范。
而 bash
/zsh
/fish
/dash
等是基于该规范的实现。但 sh 的规范有些简陋,因此 bash
/zsh
不仅实现了基本功能,甚至对 sh 进行了功能的扩展。
比如在 sh 规范中并没有数组,在 bash
/zsh
中均对数组进行了实现。
比如在前端中,
ESMAScript
就是一份规范,而在 Node.js 与浏览器环境中的 Javascript 甚至Typescript
是对它的实现。
在 linux 中,拥有各种各样的 shell,比如 dash、bash、zsh 等。 如果将服务器作为个人开发服务器,则很适合将 zsh 作为个人的默认 shell。
zsh
安装zsh教程:segmentfault.com/a/119000001…
# 安装zsh
sudo apt-get install zsh
wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
vim ~/.zshrc
# 更新配置文件
source ~/.zshrc
变量定义
h = "hello"
echo $h
echo "abc-$h"
echo "abc-$habc"
echo "abc-${h}world"
# 分别打印,最好用{}表示是一个变量
# hello
# abc-hello
# abc-
# abc-helloworld
for循环
批量创建文件
我们可以先用echo
打印要执行的字符串,然后再执行那个命令,防止出错
批量修改文件
将week -> charapter
- 先取得文件名称
- 去除week
- 在前面加上charapter
- 打印出指令字符串
- 发现没有问题,直接执行就欧克了