Shell 基本笔录

2024-01-07 06:10
文章标签 基本 shell 笔录

本文主要是介绍Shell 基本笔录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 神秘代码
    • 获取 OS Kernel CPU MEM DISK 信息
    • 第一行代码
    • 全局运行
    • 开机启动
      • systemctl
      • rc.local
      • gnome-session-properties
    • 后台运行

文中涉及的脚本主要在 虚拟机 和 Jetson TX2 中的Ubuntu18进行测试

神秘代码

一些 字体颜色 加粗 清屏 等的神秘代码, 其实是一些控制选项, 如echo-e参数可以 启用反斜杠转义的解释

参考:

  • Git shell coloring (github.com)
  • shell脚本中echo显示内容带颜色 - lr_ting - 博客园 (cnblogs.com)
#!/bin/bash# 0 Regular
# 1 Bold, Highlight?
# 2 Dark
# 3 Italic
# 4 Underline# \033[30m — \33[37m, Foreground Color
# \033[0m Text Reset# Regular Colors, Bold+Italic+Underline
echo -e "\033[30m Black  \033[0m", "\033[1;3;4;30m Black  \033[0m"
echo -e "\033[31m Red    \033[0m", "\033[1;3;4;31m Red    \033[0m"
echo -e "\033[32m Green  \033[0m", "\033[1;3;4;32m Green  \033[0m"
echo -e "\033[33m Yellow \033[0m", "\033[1;3;4;33m Yellow \033[0m"
echo -e "\033[34m Blue   \033[0m", "\033[1;3;4;34m Blue   \033[0m"
echo -e "\033[35m Purple \033[0m", "\033[1;3;4;35m Purple \033[0m"
echo -e "\033[36m Cyan   \033[0m", "\033[1;3;4;36m Cyan   \033[0m"
echo -e "\033[37m White  \033[0m", "\033[1;3;4;37m White  \033[0m"

运行显示效果如下, 左边为规则字体0, 右边为 加粗1, 斜体3, 加下划线4 的效果

在这里插入图片描述

几种清屏的命令

# https://stackoverflow.com/questions/5367068/clear-a-terminal-screen-for-real
clear	# Clean the visible screen
clear && clear	# Clean screen and clear bufferprintf "\033c"	# 在c语言中为 printf("\033c");
printf "\x1bc"
printf "\u001bc"
printf "\ec"	# \e is ESC in bash# 可以起别名
alias cls='printf "\033c"'
clsecho -en "\ec" #thanks @Jonathon Reinhart.
# -e    Enable interpretation of of backslash escapes
# -n    Do not output a new line# \033[0;0H光标设置(y,x)=(0,0), 清屏\033[2J
echo -en "\033[0;0H\033[2J"	reset	# Clean and 1-sec delay
tput reset	# Clean without 1-sec delay# 也可以键盘按下 Ctrl + L

获取 OS Kernel CPU MEM DISK 信息

主要是 grep, awk 命令, 可以参考screenfetch, jtop之类的开源代码

#!/bin/bash# OS: Ubuntu 18.04 bionic
echo -en "\033[1;31mOS: \033[0m"
# 也可以从`lsb_release -a`里面裁
LSB_RELEASE=`cat /etc/lsb-release`
# echo $LSB_RELEASE为单行, 加""为多行
# DISTRIB_ID=Ubuntu, 用=分割, 取出第2个元素, $2可换成最后一个Filed: $NF
echo "$LSB_RELEASE" | grep DISTRIB_ID | awk -F '=' '{printf "%s ", $2}'
# DISTRIB_DESCRIPTION="Ubuntu 18.04.6 LTS", 默认空格分割, 取倒数第二个
echo "$LSB_RELEASE" | grep DISTRIB_DESCRIPTION | awk '{printf "%s ", $(NF-1)}'
# DISTRIB_CODENAME=bionic
echo "$LSB_RELEASE" | grep DISTRIB_CODENAME | awk -F '=' '{print $2}'# Kernel: 5.4.0-91-generic
echo -en "\033[1;31mKernel: \033[0m"
echo `cat /proc/sys/kernel/osrelease`# CPU
# cat /proc/cpuinfo | grep -E 'processor|model name'
# cat /proc/cpuinfo | grep -iE 'processor|model name|CPU part'
# 也可以用折叠的 cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
echo -e "\033[1;31mCPU: \033[0m"
CPU_INFO=`cat /proc/cpuinfo`
# processor       : 0
# model name      : Intel(R) Core(TM) i7-8086K CPU @ 4.00GHz
echo "$CPU_INFO" | grep -E 'processor|model name' | awk -F':' '{printf "%s",$NF} NR % 2 == 0 {print ""}'# MEM
# cat /proc/meminfo
# MemTotal:       16369576 kB
echo -en "\033[1;31mMEM: \033[0m"
MEM_INFO=`cat /proc/meminfo`
echo "$MEM_INFO" | grep MemTotal | awk '{printf "%.1f GB\n", $(NF-1)/1024/1024}'# DISK
echo -en "\033[1;31mDISK: \033[0m"
echo `df -H / | tail -1 | awk '{printf "%sB, used %sB\n", $2, $3}'`

虚拟机测试结果如下

在这里插入图片描述

TX2测试结果(sudo nvpmodel -m 0)如下

在这里插入图片描述

其中, CPU的参数人性化显示是最不好搞的:

  • 要考虑 同构/异构, 酷睿系列固然一致, 但如Jetson TX2, 是A57*4+D15*2, 手机中的处理器的异构更是常见
  • ARM的代号不是我们常见的A57/A72这种, 如0xd07 是 Cortex-A57, 还要经过翻译或者查表工作, 新来的RISCV之类的不懂也不知道啥情况
  • 要考虑功耗, 如果CPU被关掉, 很可能查不出来, 如下面的例子
# jetson TX2 默认功耗模式3, 只能看到4个A57
$ cat /proc/cpuinfo | grep -iE 'processor|model name|CPU part'
processor       : 0
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 3
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 4
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 5
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07# https://en.wikipedia.org/wiki/Comparison_of_ARMv8-A_cores
# 0xd07 是 Cortex-A57# 设置功耗模式0, 可以看到4*A57+2*D15
$ sudo nvpmodel -m 0
$ cat /proc/cpuinfo | grep -iE 'processor|model name|CPU part' 
processor       : 0
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 1
model name      : ARMv8 Processor rev 0 (v8l)
CPU part        : 0x003
processor       : 2
model name      : ARMv8 Processor rev 0 (v8l)
CPU part        : 0x003
processor       : 3
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 4
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07
processor       : 5
model name      : ARMv8 Processor rev 3 (v8l)
CPU part        : 0xd07

第一行代码

参考 Shell 教程 | 菜鸟教程 (runoob.com)

Linux的Shell脚本解释器很多, 常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash.

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序, 类似的还有指定python3运行的 #!/usr/bin/python3

如我们新建1.py

print('py3 abc')

用python3运行没有问题, 但是直接运行会报错:

$ python 1.py 
py3 abc
$ chmod 777 1.py
$ ./1.py 
./1.py: line 1: syntax error near unexpected token `'py3 abc''
./1.py: line 1: `print('py3 abc')'

我们就在第一行指定python3运行

# 先看python3在哪里
$ which python3
/usr/bin/python3# 加入第一行代码 #!/usr/bin/python3
$ vi 1.py
#!/usr/bin/python3
print('py3 abc')# 然后就可以直接运行了
$ ./1.py 
py3 abc

那我如果第一行留空, 第二行再加#!/usr/bin/python3行不行呢? 如下图

在这里插入图片描述

是运行不了的:

$ ./1.py 
./1.py: line 3: syntax error near unexpected token `'py3 abc''
./1.py: line 3: `print('py3 abc')'

所以, shell脚本别忘了第一行加上 #!/bin/bash#!/bin/sh, python3脚本也最好在开头加上 #!/usr/bin/python3(windows下的情况可能不一样, 这里不讨论)

全局运行

先来看下默认的全局PATH:

# 虚拟机中
$ echo $PATH | awk -F':' '{for(i=1;i<=NF;i++){print $i}}'
/home/d/.local/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin# TX2中
$ echo $PATH | awk -F':' '{for(i=1;i<=NF;i++){print $i}}'
/opt/ros/melodic/bin
/usr/local/cuda-10.2/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

现在~/shell路径下有脚本 abc.sh, 已加权限777

#!/bin/bash
echo "abc"

如果想打开一个终端, 不用切换路径, 就可以运行, 有N种方法, 这里介绍下常用的

把脚本文件目录加到环境变量中, 默认的全局变量可以通过修改文件 /etc/profile 或者我们熟悉的ros放置的用户目录的 ~/.bashrc添加, 以后面的为例

# 把脚本所在目录 /home/d/shell 加到环境变量中
# >> 是追加的意思
$ echo -e "\nexport PATH=\$PATH:/home/d/shell" >> ~/.bashrc
# 不打开新终端就 source ~/.bashrc
# 这样每次打开新终端, PATH变量就会自动加上/home/d/shell
# 然后在其它目录也可以直接运行 abc.sh
d@ubuntu:~$ abc.sh 
abc

把脚本移动到PATH包含的目录中, 如把脚本放到 /usr/local/bin 里面(主要是这个目录比较空), 这里重命名为xyz.sh

$ sudo mv ~/shell/abc.sh /usr/local/bin/xyz.sh
# 然后就可以直接运行
d@ubuntu:~$ xyz.sh 
abc

如果连.sh后缀也不想要, 直接xyz运行

d@ubuntu:~$ sudo mv /usr/local/bin/xyz.sh /usr/local/bin/xyz
d@ubuntu:~$ xyz
abc
d@ubuntu:~$ which xyz
/usr/local/bin/xyz

实际上, python3的文件也可以这么搞, 第一行加上 #!/usr/bin/python3, 用chmod加上执行权限, 文件去掉.py后缀, 放到/usr/local/bin下面, 也可以直接运行了, 就像装了一个APP一样

开机启动

主推systemctl, 或者用这个机制实现的rc.local

systemctl

分三步:

  • 写脚本
  • 写service
  • 启动service
######################################################
# 写脚本 /home/karoto/ha/ha.sh
# #!/bin/sh必须添加
# 写完后加执行权限 sudo chmod a+x ha.sh
# 注意 echo 'the history process' > /dev/kmsg 这个只有root可以执行#!/bin/sh
echo 'the history process' > /dev/kmsg######################################################
# 写service
# sudo vi /etc/systemd/system/ha.service[Unit]
Description=ha
[Service]
ExecStart=/home/karoto/ha/ha.sh start
[Install]
WantedBy=multi-user.target######################################################
# 启动service
sudo systemctl daemon-reload 
sudo systemctl enable ha.service 
sudo systemctl start ha.service######################################################
# 检验service
sudo systemctl status ha.service
sudo reboot
dmesg | grep -i 'the history process'######################################################
# 清理service
sudo systemctl daemon-reload 
sudo systemctl stop ha.service
sudo systemctl disable ha.service 
sudo rm -f /etc/systemd/system/ha.service

rc.local

其实还是systemctl的原理, 让rc.local开机启动, 然后我把启动脚本的命令放到rc.local里就可以了

######################################################
# 写脚本 /home/karoto/ha/ha.sh
# 加执行权限 sudo chmod a+x ha.sh#!/bin/sh
echo 'the history process' > /dev/kmsg######################################################
# 添加到rc.local
# sudo vi /etc/rc.local
# #!/bin/sh 不能少
# 添加权限 sudo chmod 777 /etc/rc.local#!/bin/sh -e
/home/karoto/ha/ha.sh &######################################################
# 写rc-local.service
# sudo vi /etc/systemd/system/rc-local.service[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no[Install]
WantedBy=multi-user.target
Alias=rc-local.service######################################################
# 启动rc-local.service
sudo systemctl daemon-reload 
sudo systemctl enable rc-local
sudo systemctl start rc-local.service######################################################
# 检验service
sudo systemctl status rc-local.service
sudo reboot
dmesg | grep -i 'the history process'######################################################
# 清理脚本
# rc-local.service就保留下来, 只删除启动的脚本
# sudo vi /etc/rc.local
# 删除 /home/karoto/ha/ha.sh

gnome-session-properties

这种方式有图形界面, 比较简单, 但上面需要root权限运行的ha.sh在这里是运行不了的.

# 创建一个脚本 /home/karoto/ha/he.sh
# 加权限 sudo chmod a+x he.sh#!/bin/sh
mkdir /home/karoto/ha/he

命令行输入 gnome-session-properties 添加为启动脚本

在这里插入图片描述

重启 sudo reboot, 可以看到/home/karoto/ha多了he文件夹.

想删除的话, gnome-session-properties选中, 点击Remove按钮删除即可

在这里插入图片描述

后台运行

后台运行脚本是很有必要的, 比如:

  • roscore 占用一个会话, 挪到后台会清爽很多
  • 很多服务器或者控制器, 如华为的MDC, 基本不用或没有显示接口, 只能ssh连上去, 如果笔记本运行一个前台脚本, 只要拔掉网线, 运行就会中断, 这是不行的
  • 一些会话一直打印一些日志, 放到后台, 需要看的时候再调出来, 会清爽很多

关键词 如 &, nohup, GNU screen, tmux, byobu, Terminator等, 或者中文搜索 终端复用器. 常见的有 screen(内部快捷键占用ctrl + a) 和 tmux (内部快捷键默认占用ctrl + b) , 一般都需要 sudo apt install 安装, 这里简要介绍下 tmux.

不看window, 先只看下tmux的session操作:

  • tmux new -s my_session, 创建并进入名为my_session的会话
  • tmux new -s my_session -d, 创建但不进入名为my_session的会话, 一般脚本中会这么写
  • Ctrl+b, d, 脱离当前会话(仍在后台运行);返回Shell界面
  • tmux ls, 显示会话列表
  • tmux a -t my_session, 连接指定会话
  • tmux kill-session -t my_session, 关闭会话my_session
  • tmux kill-session -a -t my_session, 关闭除my_session外的所有会话
  • tmux kill-server, 关闭所有会话
  • man tmux, 查看文档

下面建一个脚本, 在后台运行ping命令

$ vi test.sh
#!/bin/bash
mysession="test"
# 不管有没有, 先干掉test会话
tmux kill-session -t ${mysession}  >> /dev/null
# 新建但不进入test会话
tmux new -s ${mysession} -d
# 向test会话中发送 ping www.baidu.com 命令, 注意要加回车 ENTER
tmux send-keys -t ${mysession} "ping www.baidu.com" ENTER$ chmod 777 test.sh
$ ./test.sh# 列表中发现test会话
$ tmux ls
test: 1 windows (created Thu Jan  6 21:39:00 2022) [80x24]
# 进入test会话
$ tmux a -t test
[detached (from session test)]

发现ping已经运行了起来
在这里插入图片描述

# 按 ctrl+b, 然后按d返回shell
# 关闭所有会话
# tmux kill-server

欢迎扫描二维码关注微信公众号, 及时获取最新文章:
在这里插入图片描述

这篇关于Shell 基本笔录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/578956

相关文章

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

C 语言的基本数据类型

C 语言的基本数据类型 注:本文面向 C 语言初学者,如果你是熟手,那就不用看了。 有人问我,char、short、int、long、float、double 等这些关键字到底是什么意思,如果说他们是数据类型的话,那么为啥有这么多数据类型呢? 如果写了一句: int a; 那么执行的时候在内存中会有什么变化呢? 橡皮泥大家都玩过吧,一般你买橡皮泥的时候,店家会赠送一些模板。 上

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Java 多线程的基本方式

Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):

Java基础回顾系列-第一天-基本语法

基本语法 Java基础回顾系列-第一天-基本语法基础常识人机交互方式常用的DOS命令什么是计算机语言(编程语言) Java语言简介Java程序运行机制Java虚拟机(Java Virtual Machine)垃圾收集机制(Garbage Collection) Java语言的特点面向对象健壮性跨平台性 编写第一个Java程序什么是JDK, JRE下载及安装 JDK配置环境变量 pathHe

Gradle的基本使用

新建一个项目后,在项目文件夹下创建build.gradle文件,并加入内容:       apply plugin: 'eclipse'。    然后在终端运行gradle eclipse即可构建eclipse IDE的开发环境。    gradle默认值:gradle有些目录是有默认值存在,建议项目的配置,承袭了maven的风格,如:         java的源码目录:src/mai

QML入门之基本元素

元素分为可视元素与非可视元素,可能元素例如Rectangle、Button等。非可视元素如Timer(定时器)、MouseArea(鼠标区域)等。非可视元素一般用于操作可视元素。 基础元素 Item Item(基础元素对象)是所有可视元素的基础对象,它们都继承自Item。可是元素存在以下共有属性。 Group(分组)Properties(属性)Geometry(几何属性)x

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写