Skip to content

命令行工具

echo命令

  • -e参数使用

    echo -e 命令在 Unix/Linux 系统中用于在终端输出文本,并且允许对输出进行格式化。-e 选项使得 echo 命令能够解释转义字符,比如 \n(换行)、\t(制表符)、\b(退格)等。

    这里是一些使用 echo -e 的例子:

    1. 输出带有换行的文本

      bash
      bash复制代码
      
      echo -e "第一行\n第二行"

      这将输出两行文本,第一行是“第一行”,第二行是“第二行”。

    2. 输出带有制表符的文本

      bash
      bash复制代码
      
      echo -e "姓名\t年龄\n张三\t30"

      这将输出两行,第一行是“姓名”和“年龄”之间用制表符分隔,第二行是“张三”和“30”之间用制表符分隔。

    3. 使用颜色输出文本(注意:这依赖于终端对 ANSI 转义序列的支持):

      bash
      bash复制代码
      
      echo -e "\e[31m这是红色文本\e[0m"

      注意:上面的命令中 \e 应该是 \033 或者直接写作 \ 后跟 [,因为 \e 并不是所有 shell 都支持的转义序列。正确的命令应该是:

      bash
      bash复制代码
      
      echo -e "\033[31m这是红色文本\033[0m"

      或者更常见的写法(使用 [ 而不是 \033):

      bash
      echo -e "\e[31m这是红色文本\e[0m"  # 注意:在某些 shell 中可能需要替换为 \033  
      # 更标准的写法  
      echo -e "\e[31m这是红色文本\e[0m" | sed 's/\e/\\033/g'  # 仅为展示,实际使用时不需要 sed

      但直接写作:

      bash
      bash复制代码
      
      echo -e "\033[31m这是红色文本\033[0m"

      或者

      bash
      bash复制代码
      
      echo -e "\e[31m这是红色文本\e[0m"  # 如果你的 shell 支持 \e 作为转义

      (但请注意,\e 的支持可能因 shell 而异,\033 是更可靠的选择)

      这将输出红色的“这是红色文本”,之后文本颜色恢复为默认。

    echo -e 是处理简单文本输出和格式化的有用工具,但请注意,并非所有 shell 都以相同的方式处理转义字符,特别是在处理颜色输出时。此外,对于更复杂的文本处理任务,可能需要考虑使用 printf 命令,它提供了更多的格式化和控制选项。

find

注意:-name选项后的参数需要使用双引号括住,否则不能递归正则匹配到相应的文件或者目录

删除指定名称的目录,包括子目录内的相应目录

参考链接

bash
find . -type d -name node_modules -exec rm -rfv {} \;

排除搜索指定目录

参考链接1

参考链接2

bash
# 排除 node_modules 和 demo 开头的目录
find . -maxdepth 5 -iname "*perfor*" ! -path "*/node_modules/*" ! -path "*/demo*/*"

# 排除搜索 node_modules 目录
find . -not \( -path ./**/node_modules -prune \) -name "*encod*"

# 排除搜索 front-end 目录
find . -not \( -path ./front-end -prune \) -name "*encod*"

# 排除搜索多个目录
find . -not \( -path "./**/node_modules" -prune \) -not \( -path "./**/.idea" -prune \) -name "*test*"

搜索文件时只保留文件名称(删除文件目录路径)

bash
find . -maxdepth 1 -iname "*\.md" -printf '%f\n'

搜索 /etc 目录中后缀为 pdf 的文件

bash
find /etc -name  "*.pdf"

搜索 ./.git/objects 目录中类型为普通文件

bash
find ./git/objects -type f

搜索包含指定关键字

bash
# 搜索包含 object 关键字的目录
find . -type d -name "*object*"

# 搜索包含 encod 关键字的目录
find . -name "*encod*"

# 搜索 backup- 开头的文件夹
find /data -type d -name 'backup-*'

# 忽略大小写查找 jquery
find . -iname "*jquery*"

指定目录递归深度

参考链接

bash
# 搜索递归深度1
find . -maxdepth 1 -name "*to*"

重定向 permission deny 到 /dev/null

sh
find / -iname video_20210901*.mp4 2>/dev/null

-print0 的用法

find 命令的 -print0 参数之所以重要,主要是因为它能够以 null 字符(\0)作为文件名之间的分隔符来打印文件名,这在处理包含空格、换行符、引号等特殊字符的文件名时非常有用。这些特殊字符在 shell 和许多其他命令中通常具有特殊的含义,如果文件名中包含这些字符,而 find 没有以适当的方式分隔它们,那么后续的命令可能会错误地解释这些文件名。

以下是一个具体的例子来说明为什么 find 要使用 -print0 参数:

假设你有一个目录 /tmp/weirdnames,其中包含以下文件:

  • file1.txt
  • file with spaces.txt
  • file with newlines.txt
  • file"with"quotes.txt

如果你尝试使用不带 -print0find 命令来查找这些文件,并将结果传递给另一个命令(比如 xargs),你可能会遇到问题。例如:

bash
find /tmp/weirdnames -type f | xargs ls -l

在这个例子中,find 命令会默认以换行符作为文件名之间的分隔符来打印文件名。但是,由于 file with spaces.txtfile with newlines.txt 的文件名中包含空格和换行符,xargs 可能会将这些文件名错误地拆分成多个参数,或者将文件名的一部分与其他内容混淆。

为了避免这种情况,你应该使用 -print0 参数来确保 find 命令以 null 字符作为分隔符来打印文件名,然后结合 xargs -0 来正确处理这些文件名:

bash
find /tmp/weirdnames -type f -print0 | xargs -0 ls -l

在这个修正后的例子中,find 命令会打印出以 null 字符分隔的文件名,而 xargs -0 会读取这些以 null 字符分隔的输入项,并将它们作为单独的参数传递给 ls -l 命令。这样,即使文件名中包含空格、换行符或引号等特殊字符,它们也会被正确地处理和显示。

示例:

  • 在当前目录分别创建文件file1.txtfile with spaces.txtfile"with"quotes.txt,其中file with spaces.txt文件名称包含空格,file"with"quotes.txt文件名称包含引号。

  • find命令不使用-print0参数和xargs命令一起使用时会报告错误

    bash
    find . -type f -print0 | xargs ls -l
  • find命令使用-print0参数和xargs命令一起使用时不会报告错误

    bash
    find . -type f -print0 | xargs -0 ls -l

ln命令

硬链接使用

https://www.cnblogs.com/su-root/p/9949807.html

硬链接应用:

  • 文件备份:为了防止重要的文件被误删,文件备份是一种好的办法,但拷贝文件会带来磁盘空间的消耗。硬链接能不占用磁盘空间实现文件备份。
  • 文件共享:多人共同维护同一份文件时,可以通过硬链接的方式,在私人目录里创建硬链接,每个人的修改都能同步到源文件,但又避免某个人误删就丢掉了文件的问题。
  • 文件分类:不同的文件资源需要分类,比如某个电影即是的分类是外国、悬疑,那我们可以在外国的文件夹和悬疑的文件夹里分别创建硬链接,这样可以避免重复拷贝电影浪费磁盘空间。有人可能说,使用软链接不也可以吗?是的,但不太好。因为一旦源文件移动位置或者重命名,软链接就失效了。
shell
# 硬链接指向的是节点(inode)
# 创建普通文件
echo "hello" > 1.txt
# 创建硬链接
ln 1.txt 1.txt.hard
# 查看文件硬链接数,源文件和硬链接的硬链接数为2
ls -l
# 查看文件的inode,硬链接对应的inode和源文件一样
ls -li
# mv源文件,文件移动和重命名不会影响硬链接,因为硬链接指向的inode没有发生变化
mv 1.txt 2.txt
# 删除源文件,源文件删除不会导致硬链接断开,只会导致硬链接书减少1
rm 1.txt
# 硬链接只能够链接文件,不能链接目录
# 硬链接只能够链接相同的文件系统,因为不同的文件系统有不同的inode table

符号链接使用

符号链接应用:

  • 快捷方式:对于路径很深的文件,查找起来不太方便。利用软链接在桌面创建快捷方式,可以迅速打开并编辑文件。
  • 灵活切换程序版本:对于机器上同时存在多个版本的程序,可以通过更改软链接的指向,从而迅速切换程序版本。这里提到了python版本的切换可以这么做。
  • 动态库版本管理:不是很懂,具体可以看这里。
shell
# 软链接指向的是路径(path)
# 创建普通文件
echo "hello" > 1.txt
# 创建符号链接
ln -s 1.txt 1.txt.soft
# 查看符号链接执行的源文件
ls -l
# 查看文件的inode,符号链接和源文件的inode不一样
ls -li
# 删除和移动源文件,会导致符号链接失效,因为符号链接指向文件路径的
# 符号链接能够链接文件和目录
# 符号链接能够链接不同的文件系统,因为符号链接指向文件的路径

# 创建目录的符号链接需要先切换到目标目录中,否则在创建时会报告错误
# 错误的创建命令
ln -s ../../demo-english/ docs/english-learning
# 正确的创建命令
(cd docs && ln -s ../../../demo-english english-learning)

符号链接与硬链接的区别

https://www.php.cn/linux-491726.html

tr命令

删除字符命令,可以用于输出openssl rsa key以便不需要手动删除rsa key中的换行符号。 https://stackoverflow.com/questions/800030/remove-carriage-return-in-unix

删除换行符

删除文件1.txt中的换行符并把结果输出到当前窗口中

# 1.txt内容如下
---
line 1
line 2
---

# 删除换行符号
tr -d '\n' < 1.txt

htop命令

使用top -c命令无法查看程序完整的启动命令,使用htop命令能够解决此问题,参考链接

bash
# 安装htop命令
yum install epel-release -y
yum install htop -y

# 运行htop命令
htop

# 通过键盘左右方向键滚动屏幕以查看完整的启动命令

# 通过 F6 按键调出排序字段选择窗口

# 通过 Setup > Display options > Hide userland process threads 隐藏显示线程只显示进程方式

htop 结果输出到文件

https://stackoverflow.com/questions/17534591/htop-output-to-human-readable-file

bash
# 安装 aha
yum install aha -y
echo q | htop | aha --black --line-fix > htop.html

scp命令

# 复制本地文件到远程
scp README.md [email protected]:/data/temp/

# 复制本地目录到远程
scp -r demo-bind-dns/ [email protected]:/data/demo1

# 复制远程文件到本地
scp [email protected]:/data/temp/README.md .

# 复制远程目录到本地
scp -r [email protected]:/data/demo1/ .

# 免host checking
# https://serverfault.com/questions/330503/scp-without-known-hosts-check
scp -o StrictHostKeyChecking=no 1.txt user@host_ip:1.txt

# 自动提供SSH密码
# https://www.cyberciti.biz/faq/linux-unix-applesox-ssh-password-on-command-line/
yum install sshpass -y
sshpass -p 'xxx' scp -o StrictHostKeyChecking=no 1.txt user@host_ip:1.txt

curl命令

下载包含curl工具的zip压缩包,解压后搜索curl.exe,然后复制 https://curl.haxx.se/dlwiz/?type=bin&os=Win64&flav=-&ver=-&cpu=x86_64

shell
# 使用参数-X指定http请求类型
curl -X {POST|GET|PUT|DELETE}

# 获取服务器支持http方法
curl -i -X OPTIONS http://192.168.1.178:8080/

# 隐藏curl progress bar信息-s或者--silent
curl --silent http://xxxxxx

# curl -i 或者 --include参数表示在输出http响应时候打印http请求头参数
# include the HTTP-header in the output. The HTTP-header includes things like server-name, date of the document, HTTP-version and more...

# 使用curl下载文件
curl --output apache-maven-3.6.0-bin.tar.gz http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz

# 获取接口返回数据,如下例子演示status接口是否返回Ready字符串判断应用状态
curl -s http://localhost/status

# curl使用socks5访问
# https://www.5yun.org/20639.html
curl --proxy socks5h://host:port -H 'Authorization: token xxxxx' https://raw.githubusercontent.com/wwwwu8899/chat/master/APPchat/chat-docker-mongodb/init.js

# curl使用本地dns和远程dns
# https://blog.twofei.com/714/
# 本地dns
curl --proxy socks5://host:port https://www.google.com
# 远程dns
curl --proxy socks5h://host:port https://www.google.com

# curl ouput文件时创建相应目录
# https://stackoverflow.com/questions/40367413/how-do-i-download-a-file-to-a-newly-created-directory-with-curl-on-os-x/40425734
curl -H "Authorization: token {{ var_git_api_token }}" -o /tmp/{{ item }} --create-dirs https://raw.githubusercontent.com/wwwwu8899/chat/master/APPchat/{{ item }}

# curl post 指定参数
curl -X POST http://xxx.xxx.xxx.xxx:port/api/v1/console/did/number/replace -d "uniqueId=ty189289&virtualNumber=%2B32460250887"

# curl在返回时打印输出http header和cookie等信息
curl -X POST http://192.168.1.58:8093/api/v1/voip/fs/directory -i

# curl使用http basic认证
curl -X POST http://localhost:8080/hello --user "user:password" -i

# 请求头参数header
# https://stackoverflow.com/questions/356705/how-to-send-a-header-using-a-http-request-through-a-curl-call
curl -X POST -v 192.168.1.40:82/api/v1/message/getImageSize -H "token:xxxxxxxxx"

# 不压缩并打印下载字节数
# https://stackoverflow.com/questions/9190190/how-to-use-curl-to-compare-the-size-of-the-page-with-deflate-enabled-and-without
curl -X POST --silent --output /dev/null --write-out '%{size_download}' http://192.168.3.14:80/api/v1/downloadFile

# 压缩并打印下载字节数
# https://stackoverflow.com/questions/9190190/how-to-use-curl-to-compare-the-size-of-the-page-with-deflate-enabled-and-without
curl -X POST --compressed --silent --output /dev/null --write-out '%{size_download}' http://192.168.3.14:80/api/v1/downloadFile

# 通过命令行参数-v调试发现--compressed参数实际上是在请求头中添加Accept-Encoding: deflate, gzip,相应头中添加Content-Encoding: gzip

# 发送multipart/form-data、application/x-www-form-urlencoded、application/json请求
# https://stackoverflow.com/questions/52320831/curl-send-json-as-x-www-form-urlencoded

curl -X POST -d "param1=v1" -H "Content-Type: application/x-www-form-urlencoded" http://localhost:8080/api/v1/testPostSubmitParamByFormUrlencoded1

curl -X POST -F "param1=v1" -H "Content-Type: multipart/form-data" http://localhost:8080/api/v1/testPostSubmitParamByMultipartFormData

curl -X POST -d '{"param1":"v1"}' -H "Content-Type: application/json" http://localhost:8080/api/v1/testPostSubmitParamByJSON

# curl post提交从文件读取并提交JSON数据
# https://gist.github.com/ungoldman/11282441
# data.json内容:
{"kind":"Event","apiVersion":"v1","metadata":{"name":"deployment1-5d9c9b97bb-4jlgb.100","namespace":"default","creationTimestamp":null},"involvedObject":{"kind":"Website","namespace":"default","name":"test","uid":"f637afc8-51de-4b09-a3ab-3254672b1a55","apiVersion":"v1","resourceVersion":"8904043"},"reason":"Reason Test","message":"Message Test","source":{"component":"my-source-test"},"firstTimestamp":"2023-12-08T02:40:54Z","lastTimestamp":"2023-12-08T02:40:54Z","count":1,"type":"Warning","eventTime":null,"reportingComponent":"my-source-test","reportingInstance":""}

curl -X POST -H "Content-Type: application/json" -d @./data.json http://127.0.0.1:8001/api/v1/namespaces/default/events

302 重定向

bash
curl -i -L http://localhost:8080
  • -L 参数就是用来告诉curl自动执行重定向的。

打印详细的通信过程

bash
curl --verbose https://www.baidu.com

跨域测试

注意:下面的实验需要借助示例测试https://gitee.com/dexterleslie/demonstration/tree/master/demo-spring-boot/demo-spring-boot-mvc

使用 GET 请求跨域

bash
curl -H "Origin: abc.com" --verbose  http://localhost:8080/hello
  • HTTP 头 Origin: abc.com 表示源站域名为 abc.com 以触发服务器返回跨域的响应头
  • 如果响应头中包含 Access-Control-Allow-Origin: abc.com,则表示接口支持跨域

使用 OPTIONS 探测跨域

bash
curl -H "Origin: abc.com" -H "Access-Control-Request-Method: GET" -H "Access-Control-Request-Headers: accept, content-type" -X OPTIONS --verbose  http://localhost:8080/hello
  • 服务器会返回 Access-Control-Allow-Origin: abc.com、Access-Control-Allow-Methods: GET,HEAD,POST、Access-Control-Allow-Headers: accept, content-type、Access-Control-Max-Age: 1800、Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH 等响应头表示支持跨域

使用同一个 session

https://stackoverflow.com/questions/12752555/sessions-with-curl

保存 session id 到文件 cookies.txt

bash
curl -c cookies.txt http://example.com
  • curl -c 命令在使用 curl 工具时,与 -c 选项一起,主要用于保存服务器发送的 cookies 到一个文件中。这个选项后面通常会跟着一个文件名,用于指定存储 cookies 的具体文件。如果没有指定文件名,curl 会默认创建一个名为 cookies.txt 的文件来存储 cookies。

从文件中读取 cookies

bash
curl -b cookies.txt http://example.com
  • 如果你之前使用 curl -c 保存了 cookies 到一个文件(比如 cookies.txt),你可以使用 -b 选项将这个文件的内容作为 cookies 发送到服务器

在命令行中指定 cookies

bash
curl -b "sessionid=abc123; username=johndoe" http://example.com
  • 这个命令会在访问 http://example.com 时发送两个 cookies:sessionidusername

注意事项

  • 如果同时使用了 -c(保存 cookies)和 -b(发送 cookies)选项,curl 会先读取 -b 指定的 cookies(如果有的话),然后在请求结束后,将服务器返回的新 cookies(如果有的话)保存到 -c 指定的文件中。
  • 如果 -b 后面没有跟着文件名,但是直接跟着了 name=value 对,那么这些 cookies 只会对当前请求有效,不会被保存到文件中。

yum命令

# 显示redis所有版本
yum list --showduplicates redis

# 安装指定版本redis,yum install redis-<version>
yum install redis-3.2.11-1.el6

# 搜索安装
yum search openjdk

# 清除yum缓存,删除/var/cache/dnf目录下yum缓存数据
yum clean all

# 创建yum缓存,下载远程yum源仓库数据到本地目录/var/cache/dnf目录
yum makecache

ssh命令

# 指定私钥
ssh -i private.key root@xxx

# 免host checking
# https://tecadmin.net/disable-strict-host-key-checking-in-ssh/
ssh -o StrictHostKeyChecking=no user@host_ip

# ssh执行命令
ssh -o StrictHostKeyChecking=no user@host_ip date > /tmp/.temp.txt

# ssh一次执行多条命令
ssh -o StrictHostKeyChecking=no user@host_ip "date > /tmp/.temp.txt; uname -a"

# 自动提供SSH密码
# https://www.cyberciti.biz/faq/linux-unix-applesox-ssh-password-on-command-line/
yum install sshpass -y
sshpass -p 'xxx' ssh -o StrictHostKeyChecking=no root@host_ip

ssh免密码配置

https://www.itzgeek.com/how-tos/linux/centos-how-tos/how-to-setup-ssh-passwordless-login-on-centos-8-rhel-8.html

# 在用户目录 /root/.ssh/中生成名为id_rsa和id_rsa.pub的公钥和私钥
ssh-keygen -t rsa

# 登录到被连接的服务器把公钥加入到authorized_keys文件(NOTE:公钥格式是ssh-rsa+空格开头,两个==结尾,中间内容不能换行,例如下面:)
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAfeJQAAAQEAjKTZJf5zQEMv0ZMNYWJpY0SWih1pNF8HDjCQFGKd6JbGcAlFTV/r3PzIf4LdeywyWVw4IdX3AvQCp724nbjyMNZlg/CAOjhOa2x6YRWPcVjLhA09PGzFQuRY4ZwWpZFyFtbB36cfOwe4dk1RjdBuUvCgE/jEqRKrZskNkK0fjuIa77XJg5mvQk3u6IzPPyikgk2heI0+nCxTISfQXIq5n9fnP8/BkE29RH/4044PCJBb/ZkceSC4c59KnYlyPJPYkwER+pi74FvGN5TE6YgueP2aHC5Bni+0cMsAAE7k8DaG/HdpTDsBZzn9fKWsuq+fi71G1ivPOYLXzFytG0Wyhw==

# 修改private key权限为属主只读
chmod 400 id_rsa

# 使用private key: id_rsa测试连接192.168.1.151
ssh - i id_rsa [email protected]
ssh -p50111 [email protected] 

# 在主机上使用ssh-agent管理私有秘钥,但是主机重启后秘钥丢失,因为ssh-agent把秘钥存放在内存
ssh-agent bash 启动ssh-agent
ssh-add ~/.ssh/id_rsa 添加私有秘钥
ssh-add -d ~/.ssh/id_rsa 删除私有秘钥
ssh-add -l 查看私有秘钥
ssh [email protected]

ssh端口转发(port forwarding)

https://www.jianshu.com/p/50c4160e62ac

端口转发windows服务器端使用bitvise服务器

使用-f可以使ssh进程后台运行

本地端口转发

本地端口转发:创建监听本地端口(执行ssh命令的计算机)的ssh进程

  • 例子:vm1监听本地端口44567接收用户请求后转发给跳板机vm2端口22,vm2再转发给vm3 端口80,ssh进程监听44567端口在vm1运行 [root@vm1 ~] ssh -o ServerAliveInterval=60 -gNT -L 44567:vm3:80 root@vm2
  • 例子:vm1监听本地端口44567接收用户请求后转发给跳板机vm1端口22,vm1再转发给vm3端口80,ssh进程监听44567端口在vm1运行 [root@vm1 ~] ssh -o ServerAliveInterval=60 -gNT -L 44567:vm3:80 root@vm1
  • 例子:vm1监听本地端口44567接收用户请求后转发给跳板机vm3端口22,vm3再转发给vm3端口80,ssh进程监听44567端口在vm1运行 [root@vm1 ~] ssh -o ServerAliveInterval=60 -gNT -L 44567:localhost:80 root@vm3
  • 例子:本地端口转发,命令在本机上执行并监听端口8888,本机端口8888接收到数据通过ssh隧道转发到192.168.1.54,192.168.1.54转发数据到192.168.1.58:8080 ssh -L 8888:192.168.1.58:8080 192.168.1.54
  • 例子:本地端口转发,命令在本机上执行并监听端口8888,本机端口8888接收到数据通过ssh隧道转发到本机,本机转发数据到192.168.1.58:8080 ssh -L 8888:192.168.1.58:8080 127.0.0.1

远程端口转发

远程端口转发:创建监听远程端口(被ssh的远程计算机)的ssh进程,NOTE: 远程端口转发类型监听客户端链接端口ssh配置需要修改/etc/ssh/sshd_config文件GatewayPorts yes并且使用0.0.0.0:44567:localhost:80方式绑定到所有网卡

  • 例子:vm1监听本地端口44567接收用户请求后转发给vm2端口22,vm2再转发 给vm3端口80,ssh进程监听44567端口在vm1运行 [root@vm2 ~] ssh -o "ServerAliveInterval 60" -NT -R 44567:vm3:80 root@vm1
  • 例子:使用/usr/keys/k1远程端口连接[email protected]:44770并在23.43.56.124监听44890数据转发到192.168.1.65:8090 ssh -o TCPKeepAlive=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=30 -o ExitOnForwardFailure=no -p44770 -i /usr/keys/k1 -NTf -R 0.0.0.0:44890:192.168.1.65:8090 [email protected]
  • 例子:服务器23.91.97.126监听端口44791转发到服务器192.168.1.53:5900 ssh -o TCPKeepAlive=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=30 -o ExitOnForwardFailure=no -p44790 -i /path/to/ssh/private/key -NTf -R 0.0.0.0:44791:192.168.1.53:5900 [email protected]

使用 ssh 动态端口转发配置 socks5 代理服务

https://www.cnblogs.com/zangfans/p/8848279.html

创建 socks5 服务

sh
ssh -NTf -D 0.0.0.0:10080 -p22 root@localhost
ssh -NTf -D 0.0.0.0:10080 -p22 -i /private/key/path root@localhost

配置浏览器使用socks5连接服务器1080端口实现代理上网,或者使用下面命令测试 socks5 服务是否正常

sh
git clone https://github.com/cmu-db/benchbase.git --config 'http.proxy=socks5://192.168.1.55:1080'

netcat、nc命令

https://www.cnblogs.com/nmap/p/6148306.html

netcat安装

bash
# centOS6和centOS8安装netcat
yum install nc

tcp测试

bash
# 监听本地80端口
nc -l 80

# 使用telnet连接80端口
telnet 192.168.1.23 80

# 使用nc探测端口是否打开,-v表示verbose,-w等待连接超时时间,-z只是端口扫描不发送数据
nc -v -w 10 -z xxx.xxx.xxx.xxx 88

# 重复探测端口是否打开直到成功
while ! nc -w 5 -z 192.168.1.188 22; do echo "retry ..."; sleep 2; done

# Windows平台使用telnet程序测试
# https://www.acronis.com/en-us/articles/telnet/
telnet 192.168.1.34 81

# Linux 平台使用netcat、nc程序测试
# https://www.tecmint.com/check-remote-port-in-linux/
nc -zv 192.168.1.34 81

udp测试

bash
# 服务器端在30001端口处理udp数据,这条命令会让netcat监听指定端口的UDP数据,并将接收到的数据回显到屏幕上。
# 注意:命令在服务器端执行
nc -ul 30001

# 客户端发送数据到服务器以测试udp,执行这条命令后,netcat会进入交互模式,你可以输入数据并按Enter键发送,服务端会显示客户端发送过来的数据
# 注意:命令在客户端执行
nc -u <服务器ip地> 30001

tar命令

bash
# 不解压查看tar归档文件内容
# https://askubuntu.com/questions/392885/how-can-i-view-the-contents-of-tar-gz-file-without-extracting-from-the-command-l
tar -tf filename.tar.gz

# -z参数使用gzip压缩文件
tar -cvzf tomcat-lh-management.tar tomcat-lh-management 压缩文件夹
tar -xvzf tomcat-lh-management.tar 解压文件夹

# 压缩指定文件main.tf和public.key到文件demo.tar.gz
tar -cvzf demo.tar.gz main.tf public.key


# 压缩文件夹但不打包绝对路径,-C表示先切换到/usr/local目录
# https://stackoverflow.com/questions/18681595/tar-a-directory-but-dont-store-full-absolute-paths-in-the-archive
tar -cvzf tomcat-lh-management.tar -C /usr/local tomcat-lh-management

# 压缩文件夹不包含父目录,解压之后直接会把所有文件解压到当前目录
# https://unix.stackexchange.com/questions/168357/creating-a-tar-archive-without-including-parent-directory
cd /usr/temp1
tar -cvzf 1.tar *

# 保留属主和权限信息
tar --same-owner -cvzpf tomcat-hm-denmark.tar tomcat-hm-denmark/

# tar解压到指定目录,把tar.gz解压到/tmp文件夹
# x:代表“extract”(提取),表示从归档文件中提取文件。
# z:代表通过gzip进行压缩或解压缩。如果归档文件是通过gzip压缩的(即文件扩展名为.tar.gz或.tgz),则此选项告诉tar命令在提取之前先解压缩文件。
# v:代表“verbose”(详细模式),表示在提取文件时显示进度信息,比如正在被提取的文件名。
# f:代表“file”(文件),用于指定归档文件的名称。这个选项后面紧跟归档文件的名称。
tar -xzvf archive.tar.gz -C /tmp

使用多核cpu压缩文件

pigz是一个gzip的并行版本,它可以利用多个CPU核心来加速压缩和解压缩过程。通过指定tar命令使用pigz作为压缩程序,可以实现tar命令的并行压缩。

bash
# ubuntu安装pigz
sudo apt-get install pigz

# centOS安装pigz
sudo yum install pigz

# 使用以下命令来将tar命令与pigz结合使用,实现并行压缩
# --use-compress-program=pigz:指定tar命令使用pigz作为压缩程序。
# -c:创建一个新的压缩包文件。
# -f:指定压缩包的名称。
# archive.tar.gz:要创建的目标文件名。
# files:要压缩的文件或目录列表,可以用空格分隔。
tar --use-compress-program=pigz -cvf archive.tar.gz files

zipunzip命令

bash
# zip压缩和unzip解压缩命令详解
https://blog.csdn.net/CareChere/article/details/50844846

# 把chat目录内容压缩到chat.zip
zip -r chat.zip chat

# 把当前目录所有内容压缩到chat.zip,解压时没有子目录
zip -r chat.zip .

# unzip解压
unzip mydata.zip -d mydatabak

# 解压文件夹包含中文目录或者文件名称
# https://www.jb51.net/article/123666.htm
unzip -O CP936 chat.zip -d chat

# 使用 unzip 命令解压 war 后缀的文件,解压 test.war 到 test 目录
unzip test.war -d test

jq命令

Linux jq 命令讲解与实战操作(json字符串解析工具)

jq是一个强大的命令行工具,用于处理JSON格式的数据。它可以帮助你查询、过滤、修改和处理JSON数据,使得在命令行环境下处理JSON变得非常方便。

shell
# 安装jq命令
yum install -y epel-release
yum install -y jq

### 查询和过滤数据
# 演示使用的JSON
[
   {
      "name":"Alice",
      "age":25,
      "city":"New York"
   },
   {
      "name":"Bob",
      "age":30,
      "city":"Los Angeles"
   },
   {
      "name":"Charlie",
      "age":22,
      "city":"Chicago"
   }
]

# 不选择字段,输出所有数组对象
cat 1.json | jq ".[]"

# 选择字段,查询并选择所有人的姓名
cat 1.json | jq ".[].name"

# 过滤,选择年龄大于 25 岁的人的姓名和城市
cat 1.json | jq ".[] | select(.age > 25) | .name, .city"

# 遍历数组,遍历并输出所有人的年龄
cat 1.json | jq ".[] | .age"

# 组合操作,选择年龄在 25 到 30 岁之间的人的姓名和城市,并按照姓名排序
cat 1.json | jq ".[] | select(.age >= 25 and .age <= 30) | .name, .city" | sort





### 修改数据

# 演示使用的JSON
{
   "name":"Alice",
   "age":25,
   "city":"New York"
}

# 修改字段值,修改年龄字段的值为 26
cat 2.json | jq ".age=26"

# 创建新字段,添加一个新的字段 country 并设置其值为 "USA"
cat 2.json | jq ".country=\"USA\""

# 组合操作,修改年龄字段的值为 26,并添加一个新的字段 country
cat 2.json | jq ".age=26 | .country=\"USA\""

reset命令

因为程序意外终止导致终端处于不正常状态,例如没有echo、乱码等。使用reset能够重置终端到初始默认状态。 https://www.geeksforgeeks.org/reset-command-in-linux-with-examples/

shell
# 重置终端
reset

openssl命令

shell
# 获取指定文件的二进制base64编码,tr -d '\n'表示删除换行符号
openssl base64 -in xxx.p12 | tr -d '\n'

timeout 命令

https://linuxize.com/post/timeout-command-in-linux/

timeout 命令超时时候会返回 124 代码,否则返回命令的退出状态值,-s 15 表示命令超时时候发出第 15 号信号(SIGTERM,可以通过 kill -l 查看相关值),2 表示命令的超时时间为 2 秒, sleep 10 表示休眠 10 秒。

sh
timeout -s 15 2 sleep 10

tree命令

human readable方式显示目录占用存储空间情况

sh
tree -h

指定递归深度为2

sh
# 注意:因为此命令不会统计子目录的存储空间使用,所以使用下面的命令代替此命令
tree -L 2

du -d 2 -h .

通过-a选项显示隐藏的文件或目录

sh
tree -a

通过-I参数忽略指定的模式*node**modules*

sh
tree -I "*node*|*modules*"

--prune 使树从输出中修剪空目录,与 -P 或 -I 结合使用时很有用。

bash
tree future-all -L 2 -P "pom.xml" --prune
bash
future-all
├── future-arbitrage
│   └── pom.xml
├── future-auth
│   └── pom.xml
├── future-common
│   └── pom.xml
├── future-compiler
│   └── pom.xml
├── future-deployer
│   └── pom.xml
├── future-parent
│   └── pom.xml
├── future-portal
│   └── pom.xml
└── future-widget
    └── pom.xml

vi/vim命令

vi/vim 中快速替换

参考

https://linuxize.com/post/vim-find-replace/

在命令行模式中输入 :%s/foo/bar/g 表示替换所有 foo 为 bar,% 表示整个文件,/g 表示替换当前行所有 foo。

dig命令

参考 https://phoenixnap.com/kb/linux-dig-command-examples

通过查看版本检查是否已经安装 dig 命令

sh
dig -v

debian/ubuntu 安装 dig 命令

sh
sudo apt-get install dnsutils

centOS/redhat 安装 dig 命令

sh
sudo yum install bind-utils

查询指定域名的 dns 信息

sh
dig baidu.com

指定 dns 服务器 114.114.114.114

sh
dig @114.114.114.114 baidu.com

显示所有 dns 记录

sh
dig baidu.com ANY

只显示 dns 对应的 ip 地址

sh
dig +short baidu.com

分析baidu.com dns解析过程

dig +trace baidu.com

uptime

uptime 命令是 Unix 和类 Unix 操作系统(包括 Linux)中的一个非常有用的命令行工具。它主要用于显示系统的运行时间和负载信息。当你运行这个命令时,它会给你提供三个主要的信息点:

  1. 当前时间:这是命令执行时的系统时间。
  2. 系统运行时间:自系统上次启动以来经过的时间,通常以“天、小时:分钟”的格式显示。
  3. 系统平均负载:在最近1分钟、5分钟和15分钟内,系统处于运行状态和不可中断的睡眠状态的平均进程数。这个数字可以帮助你了解系统的负载情况,即系统是否繁忙。

显示系统的运行时间和负载信息

bash
uptime

top

虚拟内存、物理内存、共享内存

top命令输出解析

Tasks: 251 total,   2 running, 249 sleeping,   0 stopped,   0 zombie
%Cpu(s): 17.2 us, 73.7 sy,  0.0 ni,  0.1 id,  0.0 wa,  3.7 hi,  5.3 si,  0.0 st
MiB Mem :   7928.6 total,   3438.2 free,   3848.7 used,    641.7 buff/cache
MiB Swap:   4028.0 total,   4028.0 free,      0.0 used.   3816.8 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                     
   1169 root      20   0 8147824   2.9g  22764 S 166.9  36.9   5:00.00 /usr/bin/java -server -XX:+HeapDumpOnOutOfMemoryError -Xms5g -Xmx5g -XX:+UseG1GC -XX:MaxGCPauseMillis=10 -XX:G1ReservePercent=20 -Djava.se+ 
   2144 root      20   0 3428536 305680 123192 S  10.0   3.8   0:14.71 /usr/bin/gnome-shell
  • Tasks: 251 total, 2 running, 249 sleeping, 0 stopped, 0 zombie
    • 系统总共有251个任务(进程或线程),其中2个正在运行,249个处于睡眠状态,没有停止或僵尸进程。
  • %Cpu(s): 17.2 us, 73.7 sy, 0.0 ni, 0.1 id, 0.0 wa, 3.7 hi, 5.3 si, 0.0 st
    • user (us): 17.2% 的CPU时间用于执行用户空间的程序(不包括内核中的时间)。
    • system (sy): 73.7% 的CPU时间用于执行内核空间中的系统调用。这个比例相当高,可能表明系统正在进行大量的I/O操作或内核级别的处理。
    • nice (ni): 几乎没有CPU时间用于执行被调整过优先级的(nice值较高的)进程。
    • idle (id): 只有0.1% 的CPU时间是空闲的。
    • iowait (wa): 没有CPU时间花费在等待I/O操作完成上。
    • hardware IRQ (hi)software interrupts (si): 分别有3.7% 和 5.3% 的CPU时间用于处理硬件和软件中断。
    • steal (st): 没有CPU时间被虚拟化环境(如虚拟机或容器)中的其他系统占用。
  • MiB Mem: 总内存7928.6MB,其中3438.2MB空闲,3848.7MB已用,641.7MB用作缓冲/缓存。
  • MiB Swap: 总交换空间4028.0MB,全部空闲,没有使用。
  • avail Mem: 可用内存(包括缓冲/缓存中的可回收部分)为3816.8MB。
  • PID 1169 是当前CPU占用率最高的进程,由root用户运行,是一个Java进程(可能是某个应用程序或服务的后端),占用了大量的CPU(166.9%)和内存(36.9%)。这个进程使用了大约5GB的堆内存(-Xms5g -Xmx5g),并配置了G1垃圾收集器。
  • PID 2144 是另一个相对高CPU占用的进程,由root用户运行,是GNOME Shell的一部分,用于提供图形用户界面。
bash
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                     
1169 root      20   0 8147824   2.9g  22764 S 166.9  36.9   5:00.00 /usr/bin/java -server -XX:+HeapDumpOnOutOfMemoryError -Xms5g -Xmx5g -XX:+UseG1GC -XX:MaxGCPauseMillis=10 -XX:G1ReservePercent=20 -Djava.se+
  • PID: 进程ID(Process ID),这是一个唯一标识符,用于区分系统上运行的每个进程。在这个例子中,进程ID是1169。
  • USER: 运行该进程的用户。在这个例子中,进程是以root用户的身份运行的。
  • PR: 优先级(Priority)。在较新的Linux内核中,这个值通常与nice值相关,但它不是直接的nice值。PR值较低表示进程具有较高的优先级。不过,请注意,实际的调度决策比这个值要复杂得多,它只是一个大致的指示。
  • NI: nice值。这是一个调整进程优先级的数值,范围从-20(最高优先级)到19(最低优先级)。默认情况下,进程的nice值为0。在这个例子中,nice值为0,表示没有调整过优先级。
  • VIRT: 虚拟内存大小(Virtual Memory Size),包括进程使用的所有内存,如代码、数据、堆栈、共享库和已映射的文件。这个值可能包括进程并未实际使用的内存,但已经被系统保留给进程。在这个例子中,虚拟内存大小为8147824KB,大约是8GB。
  • RES: 常驻内存大小(Resident Set Size),即进程当前占用的物理内存量,不包括被交换出去的部分。这个值反映了进程实际占用的物理内存量。在这个例子中,常驻内存大小为2.9GB。
  • SHR: 共享内存大小(Shared Memory),这是进程占用的共享内存量。共享内存是指可以被多个进程共同访问的内存区域。在这个例子中,共享内存大小为22764KB。
  • S: 进程状态(Status)。这个字符表示了进程当前的状态。在这个例子中,状态是S,表示进程正在睡眠(等待事件发生)。然而,由于%CPU值非常高(166.9%),这实际上意味着进程正在多个CPU核心上运行,而不是真的在睡眠。但状态字符S仍然表示它不是处于可中断的睡眠状态(如等待磁盘I/O),而是可能在执行计算任务。
  • %CPU: CPU使用率。这个值表示自进程启动以来,该进程占用的CPU时间百分比。由于是多核系统,这个值可以超过100%。在这个例子中,CPU使用率为166.9%,表明该进程正在使用多个CPU核心。
  • %MEM: 内存使用率。这个值表示进程占用的物理内存占系统总物理内存的百分比。在这个例子中,内存使用率为36.9%。
  • TIME+: CPU时间。这个值表示自进程启动以来,该进程占用的CPU总时间,包括用户态时间和系统态时间。格式通常是小时:分钟:秒。在这个例子中,CPU时间为5:00.00,即5分钟。
  • COMMAND: 启动进程的命令行名称。在这个例子中,命令行是/usr/bin/java -server -XX:+HeapDumpOnOutOfMemoryError -Xms5g -Xmx5g -XX:+UseG1GC -XX:MaxGCPauseMillis=10 -XX:G1ReservePercent=20 -Djava.se+(注意:-Djava.se+看起来像是被截断了,通常这里会跟一个完整的属性名和值)。

load average解析

参考链接

前面三个值分别对应系统当前1分钟、5分钟、15分钟内的平均load。load用于反映当前系统的负载情况,对于16核的系统,如果每个核上cpu利用率为30%,则在不存在uninterruptible进程的情况下,系统load应该维持在4.8左右。对16核系统,如果load维持在16左右,在不存在uninterrptible进程的情况下,意味着系统CPU几乎不存在空闲状态,利用率接近于100%。结合iowait、vmstat和loadavg可以分析出系统当前的整体负载,各部分负载分布情况。

Shift + H显示或者隐藏线程模式切换,如:java应用能够查看各个线程的资源情况。

指定进程id

bash
top -p156297

查看进程所有子线程cpu使用情况

bash
top -H -p156297

内存可读切换kbmbgbtb

参考链接

注意:centOS6 top命令不支持m按键切换显示单位,需要使用命令top -M,You can switch the memory unit by pressing e. E will select the memory unit in the top summary bar. Use W to permanently write your configuration to /home/user/.toprc and see also ? for more configuration options.

显示进程命令行和启动参数

bash
top -c

按照内存、cpu排序

参考链接

cpu排序,运行top命令后,键入大写P

按内存排序,运行top命令后,键入大写M

输出一次完整的系统信息

bash
top -b -n 1

top -b -n 1 命令是 top 程序的一个非常有用的组合选项,用于在批处理模式下运行 top 并只输出一次当前的系统状态。

具体来说:

  • -b(或 --batch-mode)选项使 top 程序以非交互式模式运行。这意味着它不会启动一个终端会话,也不会尝试响应用户的输入。相反,它会将输出直接发送到标准输出(通常是终端或控制台,但也可以重定向到文件或其他程序)。
  • -n 1 选项指定了 top 应该更新的次数。在这里,它被设置为 1,意味着 top 会立即收集当前的系统状态信息(包括 CPU 使用率、内存使用情况、进程列表等),然后输出这些信息并退出。由于只更新了一次,所以你不会看到 top 的动态更新界面。

将这两个选项组合在一起,top -b -n 1 就成为了一个强大的工具,可以在脚本或自动化任务中捕获系统状态的静态快照。

使用top命令计算所有进程的使用内存总和

bash
top -b -n 1 | sed '1,7d' | sed 's/^[ \t]*//' | awk 'BEGIN{total=0} {if($6~"g") {gsub("g","",$6);$6=$6*1024*1024};total=total+$6} END{print "scale=4;" total "/1024/1024"}'| bc -l | awk '{print "Memory used:" $0 "GB"}'

为何上面的命令使用内存总和不等于top -c命令中的used内存值呢?

在使用 top 命令时,你可能会注意到通过 top -b -n 1 命令获取的各个进程占用的 RES(Resident Set Size,常驻集大小)内存总和与 top -c 命令中显示的物理内存使用量(used memory)不一致。这种不一致性通常是由以下几个原因造成的:

  1. 共享内存:
    • 进程间可能会共享内存区域,比如通过共享库(如 libc)或者通过特定的内存映射(如 mmap)实现的。这些共享的内存区域在 top 的 RES 列中会被每个使用该内存的进程分别计算,但在实际物理内存中只占用一次。因此,将所有进程的 RES 值相加会重复计算这些共享内存,导致总和偏大。
  2. 内核占用的内存:
    • top -c 显示的 used 内存包括了内核占用的部分,而 top -b -n 1 显示的每个进程的 RES 并不包括内核占用的内存。内核本身也需要使用一定量的物理内存来管理硬件、运行驱动程序、维护数据结构等。
  3. 缓存和缓冲区:
    • 系统中的缓存(如文件系统缓存、页表缓存等)和缓冲区(如磁盘I/O缓冲区)也会占用物理内存,但这些通常不被计算为任何进程的 RES。这些内存区域用于提高系统性能,但在 top -c 中会反映为已使用的物理内存。
  4. 精确度问题:
    • 某些情况下,top 命令显示的数值可能由于系统内部的计数机制或更新频率而略有差异。这种差异通常很小,但在大量进程或高负载情况下可能会更加明显。
  5. 未显示或隐藏的进程:
    • 某些系统进程可能不在 top -b -n 1 的输出中显示,例如内核线程或某些系统守护进程。这些进程也可能占用一定量的物理内存。

为了更准确地理解系统的内存使用情况,你可以考虑使用其他工具或命令,如 freevmstatsar(来自 sysstat 包)或 smem(一个更精确地显示共享内存使用情况的工具)。这些工具可以提供更全面的系统内存使用概览,包括共享内存、缓存、缓冲区等。

此外,如果你对某个具体进程的内存使用情况感兴趣,可以使用 pmap 命令来查看该进程的内存映射,这有助于你理解哪些内存区域是共享的,哪些是私有的。

free命令

free命令报告的buffercache理解

Linux 中的 free 命令是一个常用的实用程序,它提供有关系统内存使用情况的信息,包括物理内存和虚拟内存。当我们在终端中运行 free 命令时,它会显示几个与内存利用率相关的值。以下是这些值的含义:

  • total:此值表示系统中的物理内存 (RAM) 总量,以千字节 (KB)、兆字节 (MB) 或千兆字节 (GB) 为单位
  • used:used 值显示各种进程和操作系统本身当前正在使用的物理内存量。
  • free:free 值表示当前未使用的物理内存量。
  • shared:shared 值表示多个进程之间共享的内存。
  • buffers:buffers 值显示用于缓冲磁盘 I/O 操作的内存量。
  • cache:cache 值表示用于缓存磁盘或其他存储设备中频繁访问的数据的内存量。
  • available:available 值表示可供新进程分配的内存的估计值。它包含了用于缓冲区和缓存的内存,如果其他应用程序需要,可以释放这些内存。

需要注意的是,free 命令报告的值是动态的,会随着进程和应用程序分配或释放内存而变化。默认情况下,这些值以千字节为单位,但我们可以使用 free 命令中的适当选项(例如,free -m 表示兆字节)指定不同的单位,例如兆字节或千兆字节。

buffer理解

在 free 命令的上下文中,缓冲区代表系统内存中临时存储数据的一部分。当我们访问计算机硬盘或任何其他存储设备上的文件时,操作系统会利用缓冲区来提高效率。

缓冲区充当存储设备与访问它的应用程序或进程之间的中介。缓冲区从存储设备读取数据并存储。同样,缓冲区将数据写入存储设备并存储。这有助于减少对存储设备的直接读取或写入操作的数量,这往往比从缓冲区访问数据要慢。

缓冲区的目的是通过聚合数据并减少与频繁磁盘访问相关的开销来优化磁盘 I/O 操作。缓冲区可以保存读取和写入数据,因此它们对于提高磁盘操作的整体性能至关重要。

cache理解

另一方面,缓存是操作系统的另一种内存管理机制。缓存主要提高系统主内存 (RAM) 的性能。缓存存储经常访问的数据,与直接从主内存或磁盘检索数据相比,可以更快地进行访问。

当应用程序或进程需要主内存中的数据时,操作系统首先检查缓存中是否有数据。如果是,则从缓存中检索数据,这比访问主内存要快得多。缓存基于局部性原理运行,它存储最近访问过或可能在不久的将来访问的数据。

通过将经常使用的数据存储在更靠近 CPU 的位置,缓存可以减少内存延迟并提高整体系统性能。这有助于最大限度地减少等待从主内存中获取数据的时间,因为主内存相对较慢。

buffercache之间区别

根据 free 命令的报告,缓冲区和缓存之间的主要区别在于它们的用途和管理的数据类型。对于存储设备,缓冲区从磁盘读取或写入磁盘,从而通过临时存储数据来优化磁盘 I/O 操作。另一方面,缓存专注于通过存储频繁访问的数据来提高系统主内存的性能。

虽然缓冲区和缓存都旨在提高整体系统性能,但它们在内存层次结构中的不同级别上运行。缓冲区在存储设备级别工作,而缓存在主内存级别运行。缓冲区有助于最大限度地减少磁盘访问,而缓存旨在减少内存延迟。

当我们运行 free 命令时,缓冲区和缓存的报告值表示为这些目的分配的内存量。监控这些值可以深入了解系统中内存资源的使用情况。它还有助于识别潜在的瓶颈或改进领域。

通过实验理解buffercache

通过写入大文件触发增加cache的值

bash
dd if=/dev/zero of=test bs=1024k

查看cache

bash
free -h

更新drop_cache内核参数以清除cache

bash
# 切换到roo用户
sudo -i

echo 1 > /proc/sys/vm/drop_caches

再次查看cache值减小

bash
free -h

总结

在本教程中,我们讨论了 free 命令报告的缓冲区和缓存。我们了解到它们是操作系统采用的两种不同的内存管理机制。缓冲区通过临时存储从存储设备读取或写入的数据来优化磁盘 I/O 操作,而缓存通过将频繁访问的数据存储在主内存中来提高性能。了解这两个概念之间的区别有助于评估内存。

md5sum命令

md5sum 命令是一个在 Unix 和类 Unix 系统(如 Linux)中广泛使用的命令行工具,用于计算和验证文件的 MD5 哈希值。MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,可以产生一个128位(16字节)的散列值(通常用32位的十六进制数表示),用于确保信息传输完整一致。

基本用法

  1. 计算文件的 MD5 哈希值

    bash
    md5sum filename

    这个命令会输出文件的 MD5 哈希值,后跟文件名。

  2. 验证文件的 MD5 哈希值: 如果你有一个文件的 MD5 哈希值,并想验证该文件的完整性,可以将该哈希值与 md5sum 命令生成的哈希值进行比较。但是,md5sum 命令本身不直接支持比较操作,你通常需要手动或使用脚本进行比较。

    首先,使用 md5sum 命令生成文件的 MD5 哈希值:

    bash
    md5sum filename > file.md5

    这会将哈希值保存到 file.md5 文件中。

    然后,在需要验证文件完整性的时候,可以使用以下命令比较哈希值:

    bash
    md5sum -c file.md5

    -c--check 选项告诉 md5sum 读取 file.md5 文件中列出的哈希值,并验证它们是否与相应文件的当前哈希值匹配。

注意事项

  • 安全性:虽然 MD5 在很多场景下仍然被使用,但它已经不被认为是一个安全的哈希算法,因为它容易受到碰撞攻击。对于需要高安全性的场景,建议使用 SHA-256 或更高版本的哈希算法。
  • 大小写敏感性:MD5 哈希值是大小写敏感的,但在大多数情况下,使用 md5sum 命令生成的哈希值会以全小写形式显示。
  • 多个文件md5sum 命令也可以同时处理多个文件,只需在命令行中列出所有要处理的文件名即可。

示例

计算并显示多个文件的 MD5 哈希值:

bash
md5sum file1.txt file2.txt

这将为 file1.txtfile2.txt 分别显示 MD5 哈希值。

hostnamectl命令

设置主机名称为k8s-master

bash
hostnamectl set-hostname k8s-master

awk命令

Linux三剑客之awk命令

awk命令语法基础

awk 是一种强大的文本处理工具,它基于模式扫描和处理语言。awk 的基本语法结构包括程序(program)、模式(pattern)和动作(action)三个主要部分。尽管这三个部分不是每次都必须明确出现,但它们共同构成了 awk 工作的基础。

基本语法

bash
awk 'pattern { action }' input_file(s)
  • pattern(可选):一个条件表达式,用于指定哪些输入行应该被处理。如果省略,awk 会对输入文件的每一行都执行动作。
  • action(可选):一系列 awk 语句,当输入行匹配模式时执行。如果省略动作,并且指定了模式,则默认动作是打印匹配的行(即 {print $0})。
  • input_file(s)(可选):一个或多个输入文件名。如果省略,awk 会从标准输入(stdin)读取数据。

示例

  1. 打印文件内容(无模式,默认动作):
bash
awk '{print $0}' filename

这等同于 cat filename,因为 awk 会对每一行执行默认的打印操作。

  1. 仅打印包含特定文本的行
bash
awk '/text_to_match/ {print $0}' filename

这会查找包含 text_to_match 的行,并打印它们。

  1. 修改字段分隔符

默认情况下,awk 使用空格作为字段分隔符。你可以使用 -F 选项来指定不同的分隔符。

bash
awk -F: '{print $1}' /etc/passwd

这会以冒号(:)为分隔符,打印 /etc/passwd 文件中每行的第一个字段(即用户名)。

  1. 使用 BEGIN 和 END 块

BEGIN 块在读取任何输入行之前执行,而 END 块在所有输入行都被处理之后执行。

bash
awk 'BEGIN {print "Start processing"} {print $0} END {print "Done processing"}' filename

这会在处理文件之前打印 "Start processing",然后打印文件内容,最后在处理完所有行后打印 "Done processing"。

  1. 内置变量和函数

awk 有许多内置变量(如 NR(Number of Records) 表示当前记录号,即行号)和函数(如 length() 用于获取字符串长度)。

bash
awk '{print NR, $0}' filename

这会打印每行的行号和该行的内容。

注意事项

  • awk 程序是区分大小写的。
  • 你可以在同一 awk 命令中指定多个模式-动作对,用换行符或分号分隔。
  • awk 的强大之处在于它能够在模式匹配时执行复杂的文本处理和数据转换。

awk 的语法和功能远不止这些,但它提供的这些基本元素是理解和使用 awk 的关键。通过组合这些元素,你可以编写出强大的文本处理脚本。

awk命令用法

获取jmeter master pod的名称,awk默认分割是空格和tab制表符

bash
kubectl get pod | grep jmeter-master | awk '{print $1}'

打印/etc/passwd文件内容

bash
awk '{print $0}' /etc/passwd
  • $0 表示当前记录,即当前行
  • '{print $0}'表示awk执行的action打印当前行
  • printawk内置函数

将输入h,i,j使用逗号作为分割符,重新使用空格作为分割拼装输出

bash
echo h,i,j|awk -F',' '{print $1 " " $2 " " $3}'

命令 echo h,i,j|awk -F',' '{print $1 " " $2 " " $3}' 的执行过程可以分解为几个步骤来解析:

  1. echo h,i,j:这部分是命令的开始,它使用 echo 命令输出字符串 h,i,jecho 是一个常用的 Unix/Linux 命令,用于在终端显示一行文本或字符串。
  2. |:这个符号是管道(pipe)操作符。它的作用是将前一个命令的输出作为后一个命令的输入。在这个例子中,echo 命令的输出(即字符串 h,i,j)被传递给 awk 命令。
  3. awk -F',' '{print $1 " " $2 " " $3}':这是命令的主体部分,使用了 awk 这个强大的文本处理工具。
    • -F',':这是 awk 的一个选项,用于指定输入字段的分隔符。在这个例子中,分隔符被设置为逗号(,)。这意味着 awk 会将输入行(在这个例子中是 h,i,j)根据逗号分割成不同的字段。
    • '{print $1 " " $2 " " $3}':这是 awk 的动作部分,用花括号 {} 包围。它指定了对每个匹配行(在这个例子中,由于没有指定模式,所以所有行都会匹配)执行的操作。具体来说,它打印出第一个字段($1,即 h)、第二个字段($2,即 i)和第三个字段($3,即 j),每个字段之间用空格分隔。

综上所述,整个命令 echo h,i,j|awk -F',' '{print $1 " " $2 " " $3}' 的作用是将字符串 h,i,j 传递给 awk,然后 awk 根据逗号将字符串分割成三个字段(hij),并将这三个字段用空格分隔后打印出来。

使用冒号作为分割符输出第一个字符,输出文件/etc/passwd中每行的冒号分割中的第一个字符

bash
awk -F":" '{ print $1 }' /etc/passwd

只打印3到4行数据

bash
awk -F':' '{if(NR>=3&&NR<=4) print $1}' /etc/passwd

命令 awk '{if(NR>=3&&NR<=4) print $1}' /etc/passwd 的作用是处理 /etc/passwd 文件,并打印出该文件中第3行和第4行的第一个字段(通常是用户名)。下面是对这个命令的详细解析:

  1. awk:这是调用 awk 程序的命令。awk 是一种编程语言,用于在 Linux/Unix 系统中对文本和数据进行处理。
  2. '{if(NR>=3&&NR<=4) print $1}':这是传递给 awk 的程序部分,用大括号 {} 包围。在这个程序中,定义了一个条件语句 if,用于检查当前处理的记录号(NR)是否满足条件。
    • NR:是 awk 的一个内置变量,代表当前处理的记录号(在大多数情况下,就是当前行号)。
    • >=3&&<=4:这是一个逻辑表达式,表示“大于或等于3且小于或等于4”。但是,这里有一个小错误,应该是 >=3 && NR<=4(注意在 NR 前加上 NR)。不过,由于 NR 是递增的,且这个条件用于检查单个范围内的行,所以实际上 NR>=3 已经隐含了 NR<=4 的情况(在只检查两行时),但更严格的写法应该是 NR>=3 && NR<=4
    • print $1:如果条件满足,就执行这个操作,即打印当前行的第一个字段($1)。在 /etc/passwd 文件中,第一个字段通常是用户名。
  3. /etc/passwd:这是 awk 命令要处理的输入文件。/etc/passwd 是 UNIX 和类 UNIX 系统中的一个核心文件,它存储了系统上每个用户账户的基本信息。

综上所述,命令 awk '{if(NR>=3&&NR<=4) print $1}' /etc/passwd 的目的是打印出 /etc/passwd 文件中第3行和第4行的用户名。

在输入字符串I am Poe ,my qq is 33794712中用空格、逗号、空格+逗号分割字符串,再输出Poe 33794712字符串

bash
echo "I am Poe ,my qq is 33794712"|awk -F"[ ,]+" '{print $3 " " $7}'

使用END块打印awk处理的总行数,count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0

bash
awk '{count++;print $0;} END{print "user count is " count}' /etc/passwd

使用BEGINEND模块打印beginend信息

bash
awk 'BEGIN {count=0;print "[start] user count is " count} {count=count+1;print $0} END{print "[end] user count is " count}' /etc/passwd

统计文件夹下所有文件占用字节数

bash
ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is " size}'

awk逻辑运算符

bash
awk 'BEGIN{a=1;b=2;print (a>2&&b>1) " " (a==1||b>1)}'

字段数量NF内置变量,只打印字段数量为8的行

bash
echo -e "root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin:888" | awk -F ":" 'NF==8{print $0}'

行号NR内置变量,指定打印第二行数据

bash
ifconfig|awk -F [" ":]+ 'NR==2{print $0}'

OFS内置变量字段分隔符

bash
awk -F ":" 'BEGIN{OFS="#"}{print $1,$2,$3,$4}' /etc/passwd

# 和上面命令等价
awk -F : -v OFS=# '{print $1,$2,$3,$4}' /etc/passwd

在awk命令中,-v 选项用于在awk程序开始执行之前设置变量。这个选项允许你在命令行上直接为awk程序中的变量赋值,而不需要在awk程序的脚本内部使用BEGIN块或其他方式来实现。这对于传递外部参数给awk程序非常有用。

-v 选项后面跟着的是变量名和它的值,它们之间用等号(=)分隔,并且整个-v 变量名=值部分可以重复多次,以设置多个变量。

ORS内置变量输出记录分割符,使用逗号作为记录分割符

bash
awk -F : -v ORS=, '{print $1}' /etc/passwd

打印第5个字段等于root

bash
awk -F: '$5=="root" {print $0}' /etc/passwd

pattern之打印所有包含root

bash
awk '/root/{print $0}' /etc/passwd

pattern之打印第5个字段匹配root的行

bash
awk -F: '$5~/root/{print $0}' /etc/passwd

pattern只打印以指定字符串开始行https://unix.stackexchange.com/questions/72734/awk-print-line-only-if-the-first-field-start-with-string-as-linux1

awk if else if else用法

  • 判断第二个字段如果是1则输出A,如果是2则输出B,否则输出C

    bash
    echo a 1 | awk '{if($2==1) print "A"; else if($2==2) print "B"; else print "C"}'
  • if控制结构中有多条子语句,示例中如果第2列中单位为g则需要乘以两次1024准换为KB单位

    bash
    echo -e "1 1g\n2 6" | awk '{if($2~"g$") {gsub("g","",$2);$2=$2*1024*1024}; print $2 "KB"}'

判断字符串是否以指定字符串结尾

bash
echo -e "1 5g\n2 6" | awk '{if($2~"g$") print "Yes"; else print "No"}'

上面示例中~ 是模式匹配操作符,左侧是要被检查的字符串或字段,右侧是要匹配的正则表达式。

过滤输出日志中耗时的毫秒数大于指定值

日志文件内容如下:

bash
xxx耗时423毫秒
xxx耗时8900毫秒
xxx耗时3453毫秒
xxx耗时5毫秒
xxx耗时45毫秒
xxx耗时37890毫秒
xxx耗时23毫秒
xxx耗时83349毫秒

过滤耗时大于30秒的日志

bash
awk -F"耗时|毫秒" '{if($2>=30000) print $0}' 1.log

gsub函数用法

把第二列中有g结尾的列替换为空字符串

bash
echo -e "1 1g\n2 6" | awk '{if($2~"g$") {gsub("g","",$2);$2=$2*1024*1024}; print $2 "KB"}'

sed

[Linux 命令总结 sed 命令详解](https://www.cnblogs.com/ginvip/p/6376049.html

介绍

技巧:学习sed command中命令和参数用法

sed命令行格式为:sed [选项] 'command'输入文本

辅助学习使用 sed 命令的 ceshi.txt 文件

内容如下:

northwest       NW      Charles Main    3.0     .98     3       34
western         WE      Sharon Gray     5.3     .97     5       23
southwest       SW      Lewis Dalsass   2.7     .8      2       18
southern        SO      Suan Chin       5.1     .95     4       15
southeast       SE      Patricia Hemenway       4.0     .7      4       17
eastern         EA      TB Savage       4.4     .84     5       20
northeast       NE      AM Main Jr.     5.1     .94     3       13
north           NO      Margot Weber    4.5     .89     5       9
central         CT      Ann Stephens    5.7     .94     5       13

显示 ceshi.txt 内容

bash
sed '' ceshi.txt

命令 d

删除第3行。默认情况下,其余的行都被打印到屏幕上。

bash
sed '3d' ceshi.txt

删除从第三行到最后一行内容,剩余各行被打印。地址范围是开始第3行,结束最后一行。

bash
sed '3,$d' ceshi.txt

删除匹配行

bash
sed -i '/^0 17 \* \* \* cat \/dev\/null > \/usr\/local\/openresty\/nginx\/logs\/error.log/d' /var/spool/cron/root

如果行尾有逗号,就将其删除

bash
sed 's/,$//'
  • sed(stream editor)中,'s/,$//'是一个替换命令,用于删除行尾的逗号(,)。这个命令的组成如下:

    • s:表示替换(substitute)操作。

    • /,/,$/:这是一个正则表达式,用于匹配模式。其中,,是我们要查找的字符(即逗号),而$是一个特殊字符,表示行的末尾。所以,/,$/匹配的是行尾紧跟的逗号。

    • //:在第二个和第三个斜杠之间,我们没有指定任何内容,这意味着我们要将匹配到的内容(即行尾的逗号)替换为空,也就是删除它。

    综上所述,sed 's/,$//'这条命令的作用是:对于输入中的每一行,如果行尾有逗号,就将其删除。

删除行开始的空格或者制表符,参考链接

bash
sed '/s/^[ \t]*//' 1.txt

命令 s

s命令用于替换。命令末端的g表示在行内全局替换;也就是说如果每一行里出现多个west,所有的west都会被替换为north。如果没有g命令,则只将每一行的第一west替换为north

bash
sed 's/west/north/g' ceshi.txt

s命令用于替换。选线-n与命令行末尾的标志p结合,告诉sed只打印发生替换的那些行;也就是说,如果只有在行首找到west并替换成north时才会打印此行。

bash
sed -n 's/^west/north/p' ceshi.txt

当“与”符号( &)用在替换串中时,它代表在查找串中匹配到的内容时。这个示例中所有以 2 位数结尾的行后面都被加上 .5。

bash
sed 's/[0-9][0-9]$/&.5/' ceshi.txt

文件中出现的所有的Hemenway都被替换为Jones,只有发生变化的行才会打印出来。选项-n与命令p的组合取消了默认的输出。标志g的含义是表示在行内全局替换。

bash
sed -n 's/Hemenway/Jones/gp' ceshi.txt

包含在圆括号里的模式Mar作为标签1保存在特定的寄存器中。替换串可以通过\1来引用它。则Margot被替换为Marlinane

bash
sed -n 's/\(Mar\)got/\1linanne/p' ceshi.txt

修改从模式wasteast之间的所有行,将各行的行尾 ($) 替换为字符串**VACA**。换行符被移到新的字符串后面。

bash
sed '/west/,/east/s/$/**VACA**/' ceshi.txt

命令 p

默认情况下, sed把所有输入行都打印在标准输出上。如果在某一行匹配到northsed就把该行另外打印一遍,所有包含north的行会重复打印

bash
sed '/north/p' ceshi.txt

默认情况下, sed把所有输入行都打印在标准输出上。如果在某一行匹配到northsed就把该行另外打印一遍默认情况下, sed打印当前缓存区中的输入行。命令p指示sed将再次打印该行。选项-n取消 sed 取消默认打印操作。选线-n和命令配合使用,模式缓冲区内的输入行,只被打印一次。如果不指定-n选项, sed就会像上例中那样,打印出重复的行。如果指定了-n,则sed只打印包含模式north的行。

bash
sed -n '/north/p' ceshi.txt

打印模式westeast之间所有的行。如果west出现在east之后的某一行,则打印的范围从west所在行开始,到下一个出现east的行或文件的末尾(如果前者未出现)。图中用箭头表示出了该范围。

bash
sed -n '/west/,/east/p' ceshi.txt

打印从第5行开始第一个以northeast开头的行之间的所有行。

bash
sed -n '5,/northeast/p' ceshi.txt

选项 -e

选项-e用于进行多重编辑。第一重编辑编辑删除第1~3行。第二重编辑将Hemenway替换为Jones。因为是逐行进行这两行编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。例如,如果两条命令都执行的是替换,前一次替换会影响后一次替换。

bash
sed -e '1,3d' -e 's/Hemenway/Jones/' ceshi.txt

命令 a

命令a用于追加。字符串Hello, World!被加在以north开头的各行之后。如果要追加的内容超过一行,则除最后一行外,其他各行都必须以反斜杠结尾。

bash
sed '/^north/a Hello world!' ceshi.txt

命令 i

命令i是插入命令。如果在某一行匹配到模式easterni命令就在该行的上方插入命令中插入反斜杠后面后的文本。除了最后一行,

bash
sed '/eastern/i Hello,world!' ceshi.txt

命令 c

c命令是修改整行命令。该命令将完整地修改在模式缓冲区行的当前行。如果模式eastern被匹配,c命令将其后的文本替换包含eastern的行。

bash
sed '/eastern/c Hello,world!' ceshi.txt

命令 n

如果在某一行匹配到模式easternn命令就指示sed用下一个输入行(即包含AM MainJr的那行)替换模式空间中的当前行,并用Archie替换AM,然后打印该行,再继续往下处理

bash
sed '/eastern/{n;s/AM/Archie/;}' ceshi.txt

命令 y

y命令把1~3行中所有的小写命令字母都转换成了大写。正则表达式元字符对y命令不起作用。与替分隔符一样,斜杠可以被替换成其他字符。

bash
sed '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' ceshi.txt

命令 q

在某行匹配到模式Lewis时,s表示先用Joseph替换Lewis,然后q命令让sed退出

bash
sed '/Lewis/{ s/Lewis/Joseph/;q; }' ceshi.txt

设置 selinuxpermissive 模式

bash
sed -i s/^SELINUX=.*$/SELINUX=permissive/ /opt/centos7-security-harden/config
  • -i表示写文件,s/替换命令,/^SELINUX=SELINUX=开头行,.*$为任何字符结尾

设置 /usr/local/jmeter/bin/jmeter 脚本中的 HEAP= 内存

bash
grep -q "^HEAP=\"" jmeter-master-tmpl && sed -i '/^HEAP=\"/c HEAP=\"-Xmx512m -Xms512m\"' jmeter-master-tmpl || sed -i '/^# resolve links/i HEAP=\"-Xmx512m -Xms512m\"' jmeter-master-tmpl

这条命令组合的目的是在名为jmeter-master-tmpl的文件中设置或更新Java堆内存(HEAP)的大小。具体来说,它检查文件中是否已经存在以HEAP="开头的行,并根据检查结果执行不同的操作。下面是命令的详细解释:

  1. grep -q "^HEAP=\"" jmeter-master-tmpl
    • 使用grep命令以静默模式(-q)搜索jmeter-master-tmpl文件中是否存在以HEAP="开头的行。
    • 如果找到匹配项,grep命令的退出状态码为0(成功),否则为非0(失败)。
  2. sed -i '/^HEAP=\"/c HEAP=\"-Xmx512m -Xms512m\"' jmeter-master-tmpl
    • 如果grep命令找到了匹配项(即文件中已经存在设置HEAP的行),则执行此sed命令。
    • sed命令以就地编辑(-i)模式运行,直接修改文件内容。
    • '/^HEAP=\"/c HEAP=\"-Xmx512m -Xms512m\"'是一个sed脚本,用于查找所有以HEAP="开头的行,并将这些行替换为HEAP="-Xmx512m -Xms512m"。这里c命令用于替换整行内容,-Xmx512m-Xms512m分别设置了Java虚拟机(JVM)的最大和最小堆内存大小为512MB。
  3. || sed -i '/^# resolve links/i HEAP=\"-Xmx512m -Xms512m\"' jmeter-master-tmpl
    • 如果grep命令没有找到匹配项(即文件中不存在设置HEAP的行),则执行此sed命令。
    • 同样使用sed命令以就地编辑模式运行。
    • '/^# resolve links/i HEAP=\"-Xmx512m -Xms512m\"'是一个sed脚本,用于在文件中查找以# resolve links开头的行(假设这是文件中一个已知存在的注释行,用于定位插入新行的位置),并在该行之前插入HEAP="-Xmx512m -Xms512m"。这里i命令用于在匹配行之前插入文本。

综上所述,这条命令组合的作用是:如果jmeter-master-tmpl文件中已经存在设置Java堆内存大小的行(以HEAP="开头),则将其更新为HEAP="-Xmx512m -Xms512m";如果不存在这样的行,则在文件中某个已知位置(以# resolve links开头的行之前)添加一行HEAP="-Xmx512m -Xms512m"来设置Java堆内存大小。

awksed的区别

参考链接

sed:Stream Editor(流编辑器)的简称,主要用于对文本进行过滤和转换。sed以行为单位对文本进行处理,非常适合于执行文本替换、删除、新增等操作。

awk:一种编程语言,同时也是文本处理工具,主要用于在Linux/Unix下对文本和数据进行处理。awk以字段(列)为单位对文本进行细节处理,非常适合于格式化文本和数据抽取。

grep命令

递归搜索指定文件,链接

sh
grep -r "17" --include "pom.xml" .
grep -r "17" --include "*.xml" .

不搜索指定的目录或者文件

bash
grep -r "xxx" --exclude-dir mydir1 --exclude-dir mydir2 --exclude myfile1 --exclude myfile2 --exclude *.min.js

--include--exclude--exclude-dir一起使用时,--include需要放在第一,否则--include不起作用

bash
grep -r -i "j.*alloc" . --include "*.md" --exclude "*.js" --exclude "*.xml" --exclude "*.properties" --exclude "*.json" --exclude-dir node_modules

忽略大小写搜索

bash
grep -r -i "xxx" .

状态码,可以通过状态码判断内容是否存在,然后再执行后续命令,-q表示静默不输出

bash
# 无法找到Root返回状态码1
grep -q "Root" /etc/passwd; echo $?

# 找到root返回状态码0
grep -q -i "Root" /etc/passwd; echo $?

提取匹配的部分字符串(不是整行)

  • error.log内容如下:

    2024/08/10 21:03:05 [crit] 12#0: *15723691 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 11#0: *15723690 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 14#0: *15723659 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 13#0: *15723701 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 10#0: *15723674 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 15#0: *15723698 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 8#0: *15701326 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 172.169.261.139, server: localhost
  • 提取clientip地址

    bash
    grep -oE 'client: [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' error.log | awk '{print $2}'

    -o(或 --only-matching):这个选项让 grep 只输出与正则表达式匹配的部分,而不是整行。这在你只想提取文本中的特定模式时非常有用。

    -E(或 --extended-regexp):这个选项让 grep 使用扩展的正则表达式(ERE)进行匹配。扩展正则表达式比基本正则表达式(BRE)提供了更多的功能,比如更灵活的分组和选择(使用 | 表示“或”)、更简单的转义字符(例如,?+{}() 等不需要转义)等。

根据进程名称查询进程id

bash
ps aux|grep mysqld | grep -v "grep" | awk '{print $2}'
  • grep -v "grep"表示不过滤grep本身那一行输出

通配符搜索,将匹配包含 abc 和 def 以及其间可选内容的字符串

https://stackoverflow.com/questions/1069302/using-the-star-sign-in-grep

bash
grep -r -i 'abc.*def' .

xargs

介绍

xargs 是一条在 Unix 和类 Unix 操作系统中常用的命令,其全名可以理解为“execute arguments”(执行参数)。xargs 的主要作用是将来自标准输入(stdin)的数据转换成命令的参数,并执行该命令。这种转换对于处理来自其他命令的输出、特别是当输出数据不能直接作为命令参数时特别有用。以下是关于 xargs 的详细介绍:

一、基本工作原理

xargs 从标准输入中读取数据,并将这些数据转换为适合传递给其他命令的参数列表。当命令需要处理大量数据时,直接将这些数据作为参数传递可能会因为参数列表过长而导致错误(如“参数列表太长”的错误)。xargs 通过将数据分批传递给命令,可以有效避免这种问题。

二、常见用法

  1. 格式化输出
    • 多行变单行:可以将来自标准输入的多行文本转换为单行输出。
    • 指定数量分行:使用 -n 选项可以指定每行显示的参数数量。
    • 指定字符分割:使用 -d 选项可以自定义一个定界符来分割输入数据。
  2. 传递参数
    • -p 实现命令确认:在执行命令前,会先询问用户是否确认执行。
    • -I 实现参数别名:使用 -I 选项可以为输入的每个参数指定一个别名,方便在后续命令中使用。
  3. 分批执行命令
    • 当需要执行大量操作时(如删除大量文件),可以使用 xargs 将操作分批进行,以避免参数列表过长的问题。

三、示例

  1. 将大量文件复制到另一个文件夹

    bash
    find /source/directory/ -type f | xargs -n1 -i cp {} /destination/directory/

    这条命令会查找 /source/directory/ 目录下的所有文件,并将它们逐个复制到 /destination/directory/ 目录下。

  2. 从文件夹中删除多个文件

    bash
    find /var/log/ -type f -print0 | xargs -0 rm -f

    这条命令会查找 /var/log/ 目录下的所有文件,并使用 rm -f 命令删除它们。注意这里使用了 -print0-0 选项来处理文件名中的空格和特殊字符。

  3. 计算多个文件中的行数

    bash
    find /opt/ -name "*.txt" -print0 | xargs -0 wc -l

    这条命令会计算 /opt/ 目录及其子目录下所有 .txt 文件的总行数。

四、高级选项

  • -P:指定并行执行的数量。默认情况下,xargs 一次只执行一个命令。使用 -P 选项可以指定同时执行的命令数量,以利用多核 CPU 的性能。
  • -t:在执行命令之前,先打印出将要执行的命令。
  • -E:指定一个字符串作为输入结束的标志,而不是默认的 EOF。

五、注意事项

  • 当文件名或路径中包含空格、引号等特殊字符时,应使用 -print0find 命令配合,以及 -0xargs 命令配合,以确保这些特殊字符被正确处理。
  • xargs-L-I(小写的 L)和 -n 标志是互相排斥的,最后指定的标志会生效。

通过上述介绍,可以看出 xargs 是一个功能强大的命令,它可以帮助用户高效地处理大量数据,特别是当这些数据需要作为其他命令的参数时。

删除指定目录下多个文件

bash
find /var/log/ -type f -print0 | xargs -0 rm -f
  • -print0参数用于处理文件名中有空格或者其他shell特殊字符替换为null字符分割符,-0表示使用find -print0输出的null字符分割符作为xargs命令的分割符

xargs -n1 用法

bash
# 没有-n1参数时,把参数一次传递给awk命令
find . -type f -print0 | xargs -0 | awk '{print $0}'

# 使用-n1参数时,把参数一次只传递一个的方式传递给awk命令
find . -type f -print0 | xargs -n1 -0 | awk '{print $0}'
  • 主要涉及到将输入数据(如来自管道或文件的输入)转换成命令行参数,并且每次只传递一个参数给指定的命令。

xargs -ixargs -I 用法

  • -i仍然可用,并且如果未指定替换字符串,它通常会将{}作为默认的替换字符串
  • 使用-I来明确指定替换字符串
bash
# 使用-i指定默认的替换字符串{}
find . -type f -print0 | xargs -0 -i echo {}

# 使用-I指定替换字符串#sx
find . -type f -print0 | xargs -0 -I'#$x' echo '#$x'

touch命令

Linux touch命令

使用指令touch修改文件testfile的时间属性为当前系统时间

bash
touch testfile

使用指令touch时,如果指定的文件不存在,则将创建一个新的空白文件。例如,在当前目录下,使用该指令创建一个空白文件file

bash
touch file

getent命令

getent 是一个在类 Unix 系统中用于获取条目(如主机名、网络地址等)的命令行工具。它通常用于查询各种数据库,如 /etc/hosts、NIS、DNS 等。当你看到 getent ahostsv4 jmeter-slaves-svc 这样的命令时,它正在尝试解析名为 jmeter-slaves-svc 的主机名,特别是查找其 IPv4 地址。

命令解析

  • getent:这是命令的主体,用于从各种数据库获取条目。
  • ahostsv4:这是 getent 的一个选项,表示查询 IPv4 地址的主机名服务(ahostsv4)。这个选项通常用于查询 DNS,但也会检查 /etc/hosts 文件等本地资源。
  • jmeter-slaves-svc:这是要查询的主机名。

执行结果

执行 getent ahostsv4 jmeter-slaves-svc 后,你可能会看到以下几种结果之一:

  1. 成功解析: 如果 jmeter-slaves-svc 可以在 DNS 或 /etc/hosts 文件中找到对应的 IPv4 地址,getent 会输出这个地址。例如:

    10.0.0.1      jmeter-slaves-svc

    这里 10.0.0.1jmeter-slaves-svc 的 IP 地址。

  2. 未找到: 如果 jmeter-slaves-svc 无法在任何配置的源中找到,getent 可能不会输出任何内容或输出一个错误消息,这取决于具体的系统和 getent 的版本。

使用场景

这个命令在配置和管理分布式系统时非常有用,比如在使用 Apache JMeter 进行性能测试时,你可能需要确保所有参与测试的服务器(在这个例子中是 jmeter-slaves-svc)都能被正确地识别和访问。通过解析其 IP 地址,你可以验证 DNS 配置或 /etc/hosts 文件的条目是否正确,从而避免连接问题。

kubernetes环境中,使用getent命令获取无头服务jmeter-slaves-svc的所有endpoint ip地址

bash
getent ahostsv4 jmeter-slaves-svc | cut -d' ' -f1 | sort -u | awk -v ORS=, '{print $1}' | sed 's/,$//'

cut命令

使用空格为分割符号,显示每行分割后的第一个字符

bash
# example.txt文件内容如下:
John Doe 30  
Jane Smith 25  
Alice Johnson 28

cat example.txt | cut -d' ' -f1

这个命令的各个部分:

  • cut:这是调用 cut 程序的命令。
  • -d' ':这里的 -d 选项用于指定字段的分隔符。在这个例子中,分隔符被设置为空格(' ')。这意味着 cut 会将输入视为由空格分隔的多个字段。
  • -f1:这个 -f 选项后面跟着的数字 1 指定了 cut 应该输出哪个字段。在这个例子中,它告诉 cut 输出第一个字段。字段的编号从 1 开始。

wc命令

统计TIME_WAITED tcp数目

bash
netstat -an|grep "TIME_WAIT"|wc -l

sort命令

排序并去除重复的行

bash
# example.txt内容如下:
3
1
2
2
3
4
5
5

cat example.txt | sort -u

解析

  • sort:这个命令用于对文本文件的行进行排序。默认情况下,它会按照字典顺序(即 ASCII 值)对行进行排序。但是,你可以通过不同的选项来改变排序的行为,比如使用数字排序、逆序排序等。
  • -u--unique:这个选项告诉 sort 命令在输出排序后的结果时,只保留唯一的行,即去除所有重复的行。去重是基于整行内容进行的,如果两行内容完全相同,则只保留其中的一行。

按照数值排序

  • example.txt内容如下:

    Tom 122
    Alice 2
    Jordon 111
    Dexter -22
  • 按照第二个字段由大到小顺序降序排序,-n是按照数值排序,-r是降序排序,-k2按照第二个字段排序

    bash
    sort -nrk2 example.txt

bc命令

在 Unix 和类 Unix 系统(如 Linux 和 macOS)中,bc 是一个用于数学运算的命令行工具,支持整数和浮点数的运算。bc 是 "basic calculator" 的缩写,尽管其功能远不止于基本的计算器。

当你提到 bc -l 命令时,-l 选项是非常重要的,因为它告诉 bc 使用标准的数学库(通常是 GNU bc 的一部分),这包括了对浮点数的支持以及一些额外的数学函数,如 sqrt()(平方根)、log()(对数)、exp()(指数)等。没有 -l 选项时,bc 默认运行在整数模式下,不支持浮点数和这些额外的数学函数。

使用示例

浮点数运算

bash
bash复制代码

echo "scale=2; 3.14 / 2" | bc -l

这个命令会输出 1.57,其中 scale=2 设置了小数点后的位数为 2。

使用数学函数

bash
bash复制代码

echo "sqrt(16)" | bc -l

这个命令会输出 4.00,因为 16 的平方根是 4。

复杂的表达式

bash
bash复制代码

echo "scale=4; (3 + 4) * 2.5 / (11 - 4)" | bc -l

这个命令会执行一个稍微复杂的表达式,并输出结果,比如 2.5000

注意事项

  • bc 的输出精度可以通过 scale 变量来设置,该变量定义了小数点后的位数。
  • 在使用 bc 进行数学运算时,尤其是在脚本中,常常需要通过管道(|)将表达式传递给 bc,如上面的示例所示。
  • 不同的系统(如 Linux 发行版和 macOS)上安装的 bc 版本可能有所不同,但它们通常都支持 -l 选项以启用对数学库的支持。

bc 是一个强大的工具,适用于需要精确数学计算的脚本和命令行任务。

uniq命令

参考链接

uniq -c 命令在 Unix/Linux 系统中用于统计或计数文本文件中排序过的相邻行出现的次数。这个命令是 uniq 命令的一个选项,通常与 sort 命令结合使用,因为 uniq 只能对相邻的重复行进行统计。

具体来说,-c--count 选项会让 uniq 命令在每行输出之前加上该行在输入文件中连续出现的次数。

使用示例

假设你有一个名为 example.txt 的文件,内容如下:

apple  
banana  
apple  
orange  
banana  
banana

如果你直接运行 uniq -c example.txt,可能不会得到期望的结果,因为 uniq 默认只对相邻的重复行进行计数。所以,你首先需要使用 sort 命令对文件内容进行排序,然后再使用 uniq -c 来计数:

bash
bash复制代码

sort example.txt | uniq -c

执行上述命令后,你将得到如下输出:

1 apple  
  1 banana  
  1 apple  
  1 orange  
  3 banana

但注意,这里 apple 和第一个 banana 只被计数了一次,因为它们在文件中不是连续出现的。为了得到一个更直观的统计结果(即,无论是否连续,每个唯一行只出现一次,并显示其总计数),你可以使用 sortuniq -c 的组合,但随后可能需要使用 awk 或其他工具来进一步处理输出,以便合并相同行的计数。不过,对于简单的连续行计数,上面的 sort | uniq -c 就足够了。

合并相同行的计数(可选)

如果你想要合并相同行的计数(即,不考虑它们在文件中是否连续),你可以使用 awk 替代 uniq -c,或者对 uniq -c 的输出进行进一步处理。但 uniq -c 本身仅用于对相邻重复行进行计数。

例如,使用 awk 来实现这一目的:

bash
bash复制代码

awk '{a[$0]++} END {for (i in a) print a[i], i}' example.txt

这个命令会统计 example.txt 中每个唯一行出现的总次数,并打印出来,不考虑它们在文件中的顺序或是否连续。

分组统计clientip地址出现次数

  • error.log内容如下:

    2024/08/10 21:03:05 [crit] 12#0: *15723691 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 11#0: *15723690 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 14#0: *15723659 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 13#0: *15723701 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 10#0: *15723674 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 104.224.178.163, server: localhost
    2024/08/10 21:03:05 [crit] 15#0: *15723698 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 192.161.182.146, server: localhost
    2024/08/10 21:03:05 [crit] 8#0: *15701326 connect() to 172.20.1.3:8080 failed (99: Cannot assign requested address) while connecting to upstream, client: 172.169.261.139, server: localhost
  • 分组统计出现次数

    bash
    grep -oE 'client: [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' error.log | awk '{print $2}' | sort | uniq -c

command命令

在Unix-like系统(如Linux或macOS)中,command -v命令用于检查系统中是否安装了某个命令,并且这个命令是可执行的。它会返回该命令的路径,如果命令不存在,则通常不输出任何内容(但具体行为可能会因shell而异,比如bash和zsh通常不会有输出,而某些其他shell可能会有错误消息)。

这个命令特别有用,因为它允许脚本或命令行工具在不实际执行命令的情况下检查其是否可用。这对于编写可移植的脚本或工具特别重要,因为不同的系统可能安装了不同的命令集。

使用示例

bash
command -v ls

如果ls命令存在并且是可执行的,这个命令可能不会输出任何内容(取决于你的shell),但你可以通过检查命令的退出状态($?)来确认它是否成功。在bash中,如果命令存在,command -v会返回0作为退出状态;如果不存在,则返回一个非零值。

command命令中,-v参数的作用是要求command命令检查并返回指定命令的路径,如果该命令存在且可执行的话。

判断命令是否存在

bash
#!/bin/bash

command_exists() {
  command -v "$@" >/dev/null 2>&1
}

if command_exists ls; then
	echo "command ls exists"
else
	echo "command ls not exists"
fi

if command_exists ls1; then
	echo "command ls1 exists"
else
	echo "command ls1 not exists"
fi

cat命令和EOF用法

catEOF的配合使用

https://blog.csdn.net/xiaokanfuchen86/article/details/116144694

输出多行文本到testing.txt(注意:在脚本xxx.sh中最后EOF标识符前面不能有空格,一定要紧贴行首,否则报错)

bash
cat > testing.txt << EOF
{{ work01_hostname }} {{ work01_ip }}
{{ work01_hostname }} {{ work01_ip }}
EOF

# <<-EOF用法,shell脚本如下
# https://unix.stackexchange.com/questions/583782/what-is-different-between-eof-and-eof-in-bash-script
# NOTE: EOF之间的内容需要使用tab创建indent,否则<<-EOF不起作用
# https://unix.stackexchange.com/questions/76481/cant-indent-heredoc-to-match-code-blocks-indentation

#!/bin/bash

if [[ "" == "" ]]; then
	cat > testing.txt <<-EOF
		{{ work01_hostname }} {{ work01_ip }}
		{{ work01_hostname }} {{ work01_ip }}
EOF
fi

oh-my-zsh安装脚本中用法示例:

bash
  if [ -d "$ZSH" ]; then
    echo "${FMT_YELLOW}The \$ZSH folder already exists ($ZSH).${FMT_RESET}"
    if [ "$custom_zsh" = yes ]; then
      cat <<EOF

You ran the installer with the \$ZSH setting or the \$ZSH variable is
exported. You have 3 options:

1. Unset the ZSH variable when calling the installer:
   $(fmt_code "ZSH= sh install.sh")
2. Install Oh My Zsh to a directory that doesn't exist yet:
   $(fmt_code "ZSH=path/to/new/ohmyzsh/folder sh install.sh")
3. (Caution) If the folder doesn't contain important information,
   you can just remove it with $(fmt_code "rm -r $ZSH")

EOF
    else
      echo "You'll need to remove it if you want to reinstall."
    fi

exec命令

bash
exec zsh -l

命令 exec zsh -l 在Unix-like系统的shell环境中执行时,具有特定的作用。

  • exec 是一个shell内置命令,它用于替换当前shell进程(或当前shell脚本中正在执行的进程)的映像,而不是创建一个新的子进程。这意味着,当 exec 命令执行后,它后面的命令(在这个例子中是 zsh -l)将直接在当前的shell进程中运行,而当前的shell(或脚本)将不再存在。换句话说,一旦 zsh -l 启动,你就无法再返回到执行 exec zsh -l 命令之前的shell环境。
  • zsh 是Z Shell的缩写,是一种功能强大的Unix shell,提供了许多高级特性和改进的用户体验。
  • -l 参数(有时也写作 --login)告诉 zsh 以登录shell的方式启动。登录shell会读取一系列的配置文件(如 /etc/zprofile/etc/zshenv~/.zprofile~/.zshrc 等,具体取决于系统和配置),这些文件通常包含环境变量的设置、别名定义、函数定义等,用于初始化用户的shell环境。

因此,当你执行 exec zsh -l 时,你实际上是在告诉系统:“用登录模式的Z Shell替换当前的shell进程,并加载相应的配置文件来初始化我的shell环境。” 这通常用于在已经登录到系统并启动了一个不同的shell(比如bash)之后,切换到Z Shell,并希望以登录shell的方式启动它,以便加载所有必要的配置。

需要注意的是,由于 exec 会替换当前shell进程,因此如果你在图形界面的终端模拟器中执行这个命令,并且之后关闭了那个终端窗口或标签页,那么你可能需要重新打开一个终端窗口或标签页来继续你的工作,因为原来的shell进程(现在已经被 zsh 替换)已经不存在了。然而,如果你是在一个远程会话(如SSH会话)中执行这个命令,并且之后关闭了那个会话,那么你的SSH连接将会断开,因为SSH会话是建立在那个shell进程之上的。

cd命令

cd -用法

在Unix-like系统的shell中(如bash、zsh等),cd -命令是一个非常实用的命令,它允许你快速地在当前目录和你上次所在的目录之间切换。

当你使用cd命令改变目录时,shell会记住你上次所在的目录的路径。这个信息被存储在环境变量OLDPWD中。当你执行cd -命令时,shell会查看OLDPWD环境变量的值,并将当前工作目录切换到该值所指向的目录。

这个命令在你需要在两个目录之间频繁切换时特别有用,比如你可能需要在你的项目目录和源代码目录之间频繁切换,或者在你正在编辑的多个文件位于不同目录时。

示例:

bash
# 假设你当前在/home/username目录下  
cd /var/log  
# 现在你在/var/log目录下  
cd -  
# 你又回到了/home/username目录下

在上面的例子中,当你第一次执行cd /var/log时,/home/username(你之前所在的目录)被存储在OLDPWD环境变量中。然后,当你执行cd -时,shell查看OLDPWD的值,并将你的工作目录切换回/home/username

需要注意的是,cd -命令只会记住你上一次使用cd命令切换到的目录。如果你连续多次使用cd命令切换目录,OLDPWD只会更新为你最后一次使用cd命令之前的目录。因此,你不能使用cd -来遍历你之前访问过的所有目录的历史记录。如果你需要这样的功能,你可能需要考虑使用其他工具或脚本来跟踪你的目录历史。

date命令

bash
date '+%Y-%m-%d %H-%M-%S'

tcpdump命令

参考链接

抓取网卡ens160端口5060 udp数据包

bash
tcpdump -i ens160 udp port 5060 -vv

抓取网卡ens160端口5060 tcp数据包

bash
tcpdump -i ens160 tcp port 5060 -vv

指定抓取srcdst地址为120.235.182.66/32 udp数据

bash
tcpdump -i eth0 udp port 5060 and \(src net 120.235.182.66/32 or dst net 120.235.182.66/32\) -vvv

tcpdump使用-w选项输出到文件1.pcap

bash
tcpdump udp port 5060 -w 1.pcap

-w-v参数组合使用显示总共抓包数"Got x"

bash
tcpdump udp port 5060 -w 1.pcap -v

显示udprtp数据包抓包数量

bash
tcpdump udp -w 1.pcap -v

diff命令

Using ‘diff’ in Linux: A Comparison Command Guide

diff 是 Linux 和类 Unix 操作系统中的一个命令行工具,用于比较文件的内容并显示它们之间的差异。这对于代码审查、文件同步和版本控制等任务非常有用。

以两列并排的方式比较文件

bash
diff -W $(tput cols) -y 1.java 2.java

-y表示两列并排的

-W $(tput cols)表示以terminal的宽度显示两列

netstat命令

Netstat是一个命令行工具,用于显示网络连接、路由表、接口统计、伪装连接以及多播成员等信息。它广泛应用于系统管理员和网络工程师的日常工作中,是监控TCP/IP网络的一个非常有用的工具。

显示tcp连接

bash
sudo netstat -antp
  • -a:显示所有socket,包括正在监听的。
  • -n:以数字形式显示地址和端口号。
  • -t:显示TCP连接。
  • -p:显示其对应的进程。

查看当前正在监听的tcp端口

bash
sudo netstat -tl
  • -l:正在监听的端口。

统计各个tcp状态的总数

bash
sudo netstat -antp | awk '/tcp/{print $6}' | sort | uniq -c
  • awk '/tcp/{print $6}':表示忽略netstat命令的列头部。

su命令

  • su -

    su - 命令是 Unix 和类 Unix 操作系统(如 Linux)中用于切换用户身份的一个常用命令。su 是 "substitute user" 或 "switch user" 的缩写,而 - 选项用于确保切换用户时,环境变量(如 HOMESHELLPATH 等)也被切换到目标用户的环境。

    基本用法

    sh
    su - [用户名]
    • 如果省略 [用户名],默认切换到超级用户(root)。
    • 使用 - 选项时,会加载目标用户的登录 shell 和环境变量。

    示例

    1. 切换到 root 用户
    sh
    su -

    输入 root 用户的密码后,会切换到 root 用户,并加载 root 用户的登录 shell 和环境变量。

    1. 切换到其他用户
    sh
    su - username

    输入指定用户(如 username)的密码后,会切换到该用户,并加载该用户的登录 shell 和环境变量。

    注意事项

    • 使用 su - 命令时,需要知道目标用户的密码。
    • 切换用户时,请确保您有权限执行该操作,尤其是在切换到 root 用户时。
    • 为了安全起见,通常建议使用 sudo 命令而不是 su 命令进行权限提升,因为 sudo 可以更细粒度地控制哪些用户可以使用哪些命令,并且记录这些操作。

    su 的区别

    • 不带 - 选项的 su 命令(如 su username)只是简单地切换到指定用户,但不会加载该用户的登录 shell 和环境变量。这可能会导致一些路径或环境变量不正确,影响命令的执行。
    • su - 命令会加载目标用户的完整登录环境,因此更为安全和可靠。

    总结来说,su - 命令是一个强大的工具,用于在 Unix 和类 Unix 系统中切换用户身份,并确保切换到目标用户的完整登录环境。

sudo命令

sudo命令用法

how to pass environment variable to sudo su

sudo命令传递JAVA_OPTS环境变量

bash
sudo JAVA_OPTS="-Xmx1024m -Xms1024m" -u tomcat sh startup.sh

sudosu命令区别

  • sudo命令读取/etc/sudoers文件判断当前用户是否有sudo权限,是则输入当前用户密码切换到目标用户
  • su命令不需要读取/etc/sudoers文件判断当前用户是否有su权限,只需要输入目标用户密码进行用户切换
  • sudo命令使用另外用户身份执行命令
  • su命令登陆到另外用户,执行/etc/passwd中用户对应的shell

ps命令

ps auxps -ef区别

ps 命令是 Linux 和 Unix 系统中用于显示当前正在运行的进程信息的工具。ps 命令有许多选项,可以组合使用以获取特定类型的进程信息。ps auxps -ef 是两种常用的组合,它们提供了系统上所有进程的详细视图,但展示的信息格式和侧重点有所不同。

ps aux

  • a:显示与终端相关的所有进程,包括其他用户的进程。
  • u:以用户为中心的格式显示进程信息。
  • x:显示没有控制终端的进程。

ps aux 输出的列通常包括:

  1. USER:进程的所有者。
  2. PID:进程ID。
  3. %CPU:进程占用的CPU百分比。
  4. %MEM:进程占用的物理内存百分比。
  5. VSZ:进程使用的虚拟内存大小(以KB为单位)。
  6. RSS:进程使用的常驻集大小(物理内存,以KB为单位)。
  7. TTY:进程关联的终端。
  8. STAT:进程的状态(如S=睡眠,R=运行,Z=僵尸进程等)。
  9. START:进程启动时间或日期。
  10. TIME:进程使用的CPU时间。
  11. COMMAND:启动进程的命令名或命令行。

ps -ef

  • e:显示所有进程。
  • f:全格式(full-format),显示进程的层级关系(父子进程)。

ps -ef 输出的列通常包括:

  1. UID:进程的所有者用户ID。
  2. PID:进程ID。
  3. PPID:父进程ID。
  4. C:CPU使用的百分比(一个粗略的估计)。
  5. STIME:进程启动时间。
  6. TTY:进程关联的终端。
  7. TIME:进程使用的CPU时间。
  8. CMD:启动进程的命令名或命令行。

比较

  • 信息类型ps aux 更侧重于提供每个进程的资源使用情况(如CPU和内存使用率),而 ps -ef 更侧重于显示进程的层级关系(父子关系)和启动时间。
  • 可读性ps aux 的输出格式对于快速查看系统资源使用情况很有用,而 ps -ef 的输出格式更适合于理解进程之间的依赖关系。
  • 使用场景:当你需要了解哪些进程正在占用大量资源时,ps aux 更为合适;当你需要跟踪进程是如何启动的,或者想要了解进程之间的父子关系时,ps -ef 更为合适。

总之,选择使用 ps aux 还是 ps -ef 取决于你的具体需求。这两个命令都是系统管理和监控中非常有用的工具。

ifconfig

bash
ifconfig -a
  • -a--all:这个选项告诉 ifconfig 命令显示所有网络接口的信息,无论它们当前是否处于激活状态。默认情况下,ifconfig 只显示当前激活的网络接口。

ifconfig 和 netplan 关系

Netplan和ifconfig都是用于网络配置和管理的工具,但它们在Ubuntu系统中的应用和地位有所不同。

ifconfig

ifconfig是Linux中用于显示或配置网络设备(网络接口卡)的命令。它可以设置网络设备的状态,或是显示当前的设置,如IP地址、子网掩码、MAC地址等。然而,在较新的Ubuntu版本中,ifconfig已经被标记为过时,并被Netplan等更现代的网络配置工具所取代。

Netplan

Netplan是Ubuntu 17.10及更高版本中默认的网络配置工具。它是一个命令行工具,可以帮助用户轻松地配置网络接口,包括静态或动态IP地址、网关、DNS等。Netplan的配置文件使用YAML格式,这使得配置文件易于阅读和编辑,并且可以通过版本控制系统进行管理。

Netplan的主要优势包括:

  1. 提供了现代化的、易于阅读和编辑的YAML格式的配置文件。
  2. 可以轻松地管理多个网络接口和配置参数。
  3. 支持多种配置引擎,如NetworkManager、systemd-networkd和DHCP客户端等,使得Ubuntu用户可以根据自己的需求选择适当的网络配置方案。
  4. 可以提高网络配置的一致性和稳定性,自动检测网络接口和硬件变化,并自动更新配置文件。

关系与对比

  1. 历史地位:ifconfig是Linux中传统的网络配置命令,而Netplan是Ubuntu为了提供更现代、更灵活的网络配置体验而引入的工具。
  2. 配置文件:ifconfig没有专门的配置文件,其配置通常通过命令行参数实现。而Netplan使用YAML格式的配置文件,这使得配置更加结构化和易于管理。
  3. 功能与应用:ifconfig主要用于显示和配置网络接口的参数,而Netplan则提供了更全面的网络配置功能,包括静态和动态IP地址配置、网关和DNS设置等。此外,Netplan还支持基于渲染器的网络配置,可以根据不同的需求选择不同的配置引擎。
  4. 系统兼容性:ifconfig在较老的Linux系统中仍然可用,但在新的Ubuntu版本中,Netplan已经成为默认的网络配置工具。因此,对于使用新Ubuntu版本的用户来说,Netplan是更推荐的选择。

综上所述,Netplan和ifconfig都是用于网络配置和管理的工具,但Netplan在Ubuntu系统中具有更高的地位和更广泛的应用。对于使用新Ubuntu版本的用户来说,建议学习和使用Netplan进行网络配置和管理。