[Shell] 加深 Shell 的学习

109 阅读1分钟

1 Shell

shell是和计算机交互的主要方式之一,运行在终端上,可以编程做自动化。可视化界面能做的事情是有限的,因为你只能做有按钮的事情

shell用来执行程序,而不是命令,执行时带有参数,就可以修改程序行为

shell通过环境变量来确定程序的位置,从而执行它

  • echo $path会打印出程序路径列表
  • which可以查看‘名称’实际运行的程序
  • man可以查看程序的手册,相比help参数更详细更易读

shell的强大在于不同程序的组合,可以把多个程序链接起来,实现方式就是通过流

有两个主要流:输入流和输出流。默认情况下,输入流是键盘,输出流是终端

  • < 或 > 可以改变流的指向,单箭头是覆盖,双箭头是追加(cat < hello.txt > hello2.txt)
  • |(管道符)是把左边程序的输出作为右边程序的输入(ls -l / | tail -n1)
  • grep在输入流中搜索关键词输出
  • cut在输入流中选取指定内容输出

根用户一般指root用户,用户id为0,它可以在系统上做任何事情,是超级用户。大多数时候,我们不会直接操作root用户,而是创建自己的用户,但总有需要根用户执行的操作,这时候就需要运行sudo程序(这里有个技巧,执行sudo !!,就不用重新输入)

1.1 命令备忘

echo、which、man

pwd、cd [ ~ | -]

cat、ls [-l | -a]

mkdir、vim

 

拷贝:cp -rf 文件或目录 新位置        (cp命令加了-f参数仍然提示是否覆盖

移动:mv -f 文件或目录 新位置

重命名:mv 旧名字 新名字

删除:rm -rf 文件或目录

 

查看zip包:unzip -l 包名

解压zip包:unzip -o [-d 目录] 包名

 

查看进程:ps -ef | grep xxx

查看端口:netstat -lnpt

 

查看磁盘空间:df -h

查看大小:du -sh 文件或目录

怎么排查占用特别大的目录:

  1. du -sh ./*
  2. du -h 占用大的目录
  3. 搜索G,一个个看

 

实时查看文件内容:tail -f 文件

查找文件或目录(也能查历史):find 路径 [-name|-type|-size]

打开:xdg-open

 

防火墙:

如果端口没有开放,那么nginx配置的server就会无法访问

firewall-cmd --zone=public --list-ports  #查看所有开放端口

firewall-cmd --zone=public --add-port=5672/tcp --permanent  #开放5672端口

firewall-cmd --zone=public --remove-port=5672/tcp --permanent  #关闭5672端口

firewall-cmd --reload  #配置立即生效

systemctl status firewalld  #查看防火墙状态

systemctl start firewalld.service  #开启

systemctl stop firewalld.service  #关闭

systemctl restart firewalld.service  #重启

 

cURL: 发请求的程序

curl URL:(默认get)

跟随重定向:-L

输出通信的整个过程,用于调试:-v

导出文件:-O

注意:不要在vscode终端运行curl,输出有问题

 

history [1]: 查看历史记录,用例:history 1 | grep git

 

1.2 ssh 和 scp

ssh 用户名@服务器地址 [-p 端口]

 

使用ssh配置文件快速连接到远程服务器

vim ~/.ssh/config

Host 别名
HostName 服务器地址
User 用户名
IdentityFile ~/.ssh/id_rsa

配置好后,直接输入“ssh 别名”即可

 

免密

ssh-keygen

cat ~/.ssh/id_rsa.pub

 

本地上传到远程:scp -r 本地 用户名@服务器地址:远程

远程下载到本地:反过来,先写远程再写本地

 

1.3 脚本基础

shell有很多种类:bash(Linux)、zsh(MacOs)...

选择哪种?如果用mac电脑,那就用zsh,否则都用bash

bash脚本想在mac电脑执行,需要载入zsh配置文件,脚本开头加上:source ~/.zshrc

脚本应该说明使用的shell,第一行写上:#!/bin/[zsh | bash]

 

下面的教程基于bash

定义变量:foo=bar

调用:echo $foo

注意:因为空格用于分隔参数,所以不能写成foo = bar,这相当于使用第一个参数=和第二个参数bar调用foo程序

定义字符串:单引号和双引号都可以,但最好使用双引号,因为这样可以在字符串内调用变量,而单引号的字符串无法调用变量

定义函数

mcd () {
    mkdir -p "$1"
    cd "$1"
}

特殊变量:

$0 表示脚本的名称
$1 表示第1个参数,一直到$9表示第9个参数
$_ 表示获取上个命令的最后一个参数
$? 表示获取上个命令的错误代码
    0 表示一切正常,没有错误,退出
    1 表示虽然执行没问题,但没奏效
    true0false1
$# 表示参数的数量
$$ 表示程序运行的进程id,即pid
$@ 表示扩展到所有参数,类似js的rest参数

source用来执行脚本,执行完后脚本内的变量、函数就可以在终端调用

运算符:&& 和 ||

将输出转换成变量:foo=$(pwd)

控制流:for、while循环

通配符

*表示任意字符任意长度,例子:ls *.sh
?表示任意字符但只一个长度
{a,b}表示ab,例子:image.{png,jpg}

1.3.1 实用程序

ripgrep: 递归搜索当前目录以查找与模式匹配的行

convert: 处理图像

ffmpeg: 处理视频

tldr: 查看程序运行实例的手册,非常方便

fzf: 模糊搜索

broot: 快速的目录列表和导航

1.4 实例-将打包产物放入另个仓库并推送

#!/bin/zsh

current_time=$(date "+%Y年%m月%d日 %H时%M分%S秒")
project="/Users/xxx/Desktop/project"
project_a="$project/a"
project_b="$project/b"

echo "当前时间: $current_time"
echo "脚本名称: $0    参数数量: $#    pid: $$"
echo "程序开始执行..."

cd "$project_a"
# git checkout master
# git pull
npm i
npm run build

cd "$project_b"
git checkout master
git pull
cp -rf "$project_a/dist" "$project_b"
git add *
git commit -m "$current_time"
# git push -u origin "origin/master"
git push

cd ~/Desktop/notes/工具库/shell

echo "程序执行完成! 🍺"