├── 推荐开源项目:Linux Kernel - 强大的操作系统内核.md
├── Linux系统入门系列之五:数据流定向.md
├── How to Append a Line After a String in a File Using sed Command.md
├── How to Start, Stop, and Restart Services in Linux.md
├── sed:小工具,大用处.md
├── Linux04:三种软件安装方式及服务器基本环境搭建.md
├── 学编程,怎么能不懂正则表达式!.md
├── Linux系统入门系列之二.md
├── How To Build Lightweight Docker Images With Mmdebstrap In Linux.md
├── Linux系统入门系列之四:工具命令.md
├── 10个POSIX编程的代码示例.md
├── awk:强大的文本分析工具.md
├── Posix多线程编程.md
├── Linux01:概述及环境搭建.md
├── shell编程:编程就是这么简单.md
├── 73条日常Linux shell命令汇总.md
├── Linux系统安装详细教程.md
├── Linux环境都没有,怎么学编程?.md
├── Android NDK POSIX 多线程编程.md
├── How To Automate Mounting dev In Chroot Environments In Linux.md
├── Linux系统入门系列之三:初识Bash.md
├── How to install Linux on Windows with WSL.md
├── Shell脚本:常用100个shell命令使用讲解题.md
├── Linux系统入门系列之一.md
├── Linux02:常用的基本命令.md
├── Linux shell及常用36类命令汇总.md
├── 40 个简单又有效的 Linux Shell 脚本示例.md
└── 决战Linux到精通4.md
/推荐开源项目:Linux Kernel - 强大的操作系统内核.md:
--------------------------------------------------------------------------------
1 | 原文链接:https://blog.csdn.net/gitblog_00060/article/details/139163762
2 |
3 | # 推荐开源项目:Linux Kernel - 强大的操作系统内核
4 |
5 | ## 1、项目介绍
6 | Linux 内核是世界上最广泛使用的开源操作系统内核,它为各种设备提供了稳定且高效的运行环境。从智能手机到超级计算机,Linux 内核都扮演着核心角色。项目文档齐全,包括开发者指南和用户手册,以满足不同层次用户的需要。
7 |
8 | 在线阅读地址:https://www.kernel.org/doc/html/latest/
9 |
10 | ## 2、项目技术分析
11 | Linux 内核的技术栈涵盖了多进程管理、内存管理、设备驱动、文件系统等多个关键领域。采用模块化设计,允许动态加载或卸载功能,使得内核既可轻量化,也能灵活扩展。它的稳定性、安全性和性能经过无数项目验证,被誉为 IT 领域的基石之一。
12 |
13 | 开发文档遵循 Restructured Text 格式,通过 make htmldocs 或 make pdfdocs 可快速构建 HTML 和 PDF 文档,方便查阅和打印。
14 |
15 | ## 3、项目及技术应用场景
16 | - **服务器**:Linux 内核在云计算和数据中心环境中表现出色,提供高性能和低延迟。
17 | - **物联网(IoT)**:小至嵌入式设备,大至工业自动化系统,Linux 内核都能提供定制化的解决方案。
18 | - **移动设备**:Android 操作系统基于 Linux 内核,服务于全球数十亿手机和平板用户。
19 | - **桌面计算**:各种 Linux 发行版如 Ubuntu 和 Fedora 提供了友好且强大的桌面环境。
20 | - **科研与教育**:因其开放源码特性,Linux 被广泛用于学术研究和教学中。
21 |
22 | ## 4、项目特点
23 | - **开放源码**:任何人都可以查看、修改和分发代码,促进社区协作创新。
24 | - **跨平台**:支持多种硬件架构,从小型 ARM 设备到大型 IBM mainframes。
25 | - **高度可定制**:可以根据具体需求裁剪内核,实现最小化或最大化部署。
26 | - **强大生态**:拥有庞大的开发者社区和丰富的软件库,满足各类应用需求。
27 | - **持续更新**:频繁发布安全补丁和新功能,保持技术领先。
28 |
--------------------------------------------------------------------------------
/Linux系统入门系列之五:数据流定向.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/swRLSabylfS4jwQn_ao0rA
2 |
3 |
4 |
5 |
6 |
7 | # Linux系统入门系列之五:数据流定向
8 |
9 |
10 |
11 |
12 |
13 | Linux具有强大的文件信息处理系统,基于Linux系统的数据流定向、正则表达式可以方便的在服务器中处理大数据文本。接下来将带大家深入了解Linux系统文件处理规则,从而便以后各种生物信息数据的处理。
14 |
15 | ——走进Bash
16 |
17 | ## 1.数据流定向
18 |
19 | 一般命令的执行来自于标准输入(例如键盘输入,来自文件的命令也要转换为标准输入),执行完毕后将数据(处理结果或错误信息)传输到屏幕上,也即标准输出,但是这样导致屏幕十分杂乱,也不利于结果的保存查看。我们可以采用数据流定向手段将结果和错误信息传输到文件,定向方法如下:
20 |
21 | 标准输入(stdin):代码为0,使用<或<<;
22 |
23 | 标准输出(stdout):代码为1,使用>或>>;
24 |
25 | 标准错误输出(stderr):代码为2,使用2>或2>>。
26 |
27 | 具体用法如下所示:
28 |
29 | 
30 |
31 | 例如我们要运行显示时间和日期的shell脚本,并将结果保存在cal_date.txt里面:
32 |
33 | 
34 |
35 | 接下来我们运行显示生日的脚本,将结果追加在cal_date.txt中:
36 |
37 | 
38 |
39 | 注意这里使用的是>>,若是>则内容会替代而不是累加。接下来我们修改shell脚本使cal参数错误,然后运行并输出错误信息:
40 |
41 | 
42 |
43 | 也可以将正确结果与错误信息同时输出到两个文件:
44 |
45 | 
46 |
47 | 假如我们不希望在屏幕上看到错误信息,也不希望保存,直接将报错丢掉,可以使用垃圾桶/dev/null,示例如下:
48 |
49 | 
50 |
51 | 将正确结果和错误信息输出到同一个文件,可以灵活使用&符号:
52 |
53 |
54 |
55 | 
56 |
57 | 命令cat可以将文件内容转换为标准输出显示到屏幕上,同时也可以将键盘输入到屏幕上的内容写入新的文件:
58 |
59 | 
60 |
61 | 其中<<后面跟的是结束输入的关键词。采用<我们还可以使用文件来代替标准输入,例如将friends1.sh的内容作为标准输入写入一个新的文件friends2.sh,示例如下:
62 |
63 | 
64 |
65 |
66 |
67 | 命令:tee
68 |
69 | 命令tee可以起到数据流分流的作用,例如我们将数据同时显示到屏幕上(以便下一步处理)并保存到一个文件:
70 |
71 | 
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/How to Append a Line After a String in a File Using sed Command.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://www.tecmint.com/sed-add-a-line-after-string-in-file/
2 |
3 |
4 |
5 |
6 |
7 | # How to Append a Line After a String in a File Using sed Command
8 |
9 |
10 |
11 | If you’re working with text files on a Linux system, you may need to modify the contents of those files. One useful tool for this task is [sed](https://www.tecmint.com/linux-sed-command-tips-tricks/), which stands for **stream editor**, which allows you to perform various text manipulations, such as replacing text, deleting lines, and adding new lines.
12 |
13 | In this article, we’ll show you how to use `sed` to add a new line after a specific string in a file.
14 |
15 | ## What is sed?
16 |
17 | `sed` is a command-line tool used for text processing, which reads input line by line, applies the specified operation, and then outputs the result.
18 |
19 | You can use `sed` to perform tasks like:
20 |
21 | - Searching and replacing text
22 | - Inserting or deleting lines
23 | - Modifying text based on patterns
24 |
25 | In our case, we will use `sed` to add a line after a particular string in a file.
26 |
27 | ## How to Add a Line After a String in a File
28 |
29 |
30 |
31 | Let’s say you have a file called `example.txt` with the following content:
32 |
33 | ```
34 | Hello, this is a test file.
35 | This is the second line.
36 | We are learning how to use sed.
37 | This is the last line.
38 | ```
39 |
40 | Now, suppose you want to add a new line after the string “**learning how to use sed**“, you can use the following `sed` command syntax.
41 |
42 | ```
43 | sed '/pattern/a\new line of text' filename
44 | ```
45 |
46 | Let’s break down this command:
47 |
48 | - `/pattern/` is the search pattern that tells **sed** to look for a specific string in the file and replace pattern with the string you’re searching for.
49 | - `a\` is the append command that tells **sed** to add a new line after the line containing the search pattern.
50 | - `new line of text` is the text you want to add.
51 | - `filename` is the name of the file you want to modify.
52 |
53 | Let’s say we want to add the line “`This is the new line!`” after the string “`learning how to use sed`” in the file `example.txt`.
54 |
55 | ```
56 | sed '/learning how to use sed/a\This is the new line!' example.txt
57 | ```
58 |
59 | This will print the content of the file with the new line added after the matched string as shown.
60 |
61 | ```
62 | Hello, this is a test file.
63 | This is the second line.
64 | We are learning how to use sed.
65 | This is the new line!
66 | This is the last line.
67 | ```
68 |
69 | However, this command only shows the output on the terminal and does not change the file itself.
70 |
71 | If you want to save the changes directly to the file, you can use the `-i` option with `sed` to edit the file in place.
72 |
73 | ```
74 | sed -i '/learning how to use sed/a\This is the new line!' example.txt
75 | ```
76 |
77 |
78 |
79 | After running this command, the file `example.txt` will be updated with the new line added.
80 |
81 | ##### Conclusion
82 |
83 | Using `sed` to add a line after a string in a file is simple and powerful. You can easily modify files without needing to open them in a text editor. This method is particularly useful when you want to automate text file modifications or make changes to large files quickly.
84 |
85 | Remember:
86 |
87 | - Use `/pattern/a\new line` to add a line after a specific string.
88 | - Use `-i` to save changes directly to the file.
89 |
90 | With this knowledge, you can start editing files more efficiently using `sed`!
91 |
--------------------------------------------------------------------------------
/How to Start, Stop, and Restart Services in Linux.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://www.tecmint.com/systemd-service-commands/
2 |
3 |
4 |
5 | # How to Start, Stop, and Restart Services in Linux
6 |
7 |
8 |
9 | If you’re new to [Linux](https://www.tecmint.com/what-is-linux/), understanding how to manage services is an essential skill. Services are [processes that run in the background](https://www.tecmint.com/12-top-command-examples-in-linux/) to provide various functions, such as web servers, databases, or network services.
10 |
11 | As a Linux user with over a decade of experience, I can assure you that [mastering the commands](https://www.tecmint.com/essential-linux-commands/) to start, stop, and restart services will make your experience smoother.
12 |
13 | This article will guide you through the basics so that you can start, stop, or restart services depending on what you need.
14 |
15 | ## Why Do You Need to Start, Stop, or Restart Services?
16 |
17 | - **Starting a Service**: You may need to start a service after installing software or when the system boots up without automatically starting certain services.
18 | - **Stopping a Service**: Stopping a service can free up system resources or prevent unwanted programs from running.
19 | - **Restarting a Service**: If a service is malfunctioning or after making configuration changes, restarting is often the quickest way to resolve issues.
20 |
21 | ## Key Commands for Managing Services
22 |
23 | In Linux, the most common way to manage services is through the `systemd` system, which controls services on [modern Linux distributions](https://www.tecmint.com/top-most-popular-linux-distributions/).
24 |
25 | The basic commands are:
26 |
27 | ### 1. Start a Service in Linux
28 |
29 |
30 |
31 | To start a service, use the following command:
32 |
33 | ```
34 | sudo systemctl start apache2
35 | ```
36 |
37 | This command starts the **Apache** web server. If the service is not running, it will begin.
38 |
39 | ### 2. Stop a Service in Linux
40 |
41 | To stop a running service, you can use the command:
42 |
43 | ```
44 | sudo systemctl stop apache2
45 | ```
46 |
47 | This will stop the Apache web server. If it’s already stopped, the command does nothing.
48 |
49 | ### 3. Restart a Service in Linux
50 |
51 | If a service needs to be restarted (for example, after a configuration change), use:
52 |
53 | ```
54 | sudo systemctl restart apache2
55 | ```
56 |
57 | This will stop the Apache service and immediately start it again, which is useful for applying new configuration changes.
58 |
59 | ### 4. Checking the Status of a Service
60 |
61 | You can also check the status of a service to see if it is running properly.
62 |
63 | ```
64 | sudo systemctl status apache2
65 | ```
66 |
67 |
68 |
69 | This will display information about the Apache service, including whether it is active (running), inactive, or failed.
70 |
71 | ## Enabling and Disabling Services in Linux
72 |
73 | By default, some services are set to start automatically when your system boots. If you want to make sure a service starts automatically (or stops starting automatically), you can enable or disable it:
74 |
75 | ```
76 | sudo systemctl enable apache2
77 | sudo systemctl disable apache2
78 | ```
79 |
80 | ##### Conclusion
81 |
82 | Now that you know how to start, stop, and restart services in Linux, you’re well-equipped to [manage essential services](https://www.tecmint.com/chkconfig-vs-systemctl/) on your system.
83 |
84 | These commands are fundamental to ensuring your services run smoothly, whether you’re setting up a web server or troubleshooting issues. Keep [practicing these commands](https://www.tecmint.com/most-used-linux-commands/), and soon they’ll feel like second nature.
85 |
86 | If you’re new to Linux, take your time and explore the [systemctl command](https://www.tecmint.com/manage-services-using-systemd-and-systemctl-in-linux/). It’s a powerful tool that makes service management easier than ever.
87 |
--------------------------------------------------------------------------------
/sed:小工具,大用处.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/9rKG1HcryZTzzgmHeOXQKw
2 |
3 |
4 |
5 |
6 |
7 | # sed:小工具,大用处
8 |
9 |
10 |
11 | 
12 |
13 | 在学习工作中发现,在Linux中除了ll、ls、less等查看命令,sed与awk是使用最为频繁的文本编辑命令,这两个工具可以使用最简单的方法完成复杂多样的编辑任务,因此接下来将依次为大家介绍这两个工具的使用。
14 |
15 | 
16 |
17 |
18 |
19 | 
20 |
21 |
22 |
23 | 管道命令sed是一个很好的文本处理工具,主要以行为单位进行处理,可以将数据进行替换、删除、新增、选取等。sed可以处理标准输入内容或者文件,可以输出标准输出或输出到文件。sed的一般使用规则如下:
24 |
25 | ```
26 | sed -nefri '动作命令' 文件或输入
27 | ```
28 |
29 | 参数设置:
30 |
31 | -n:使用安静(silent)模式。在一般sed的用法中,所有来自STDIN的资料一般都会被列出到屏幕上。但如果加上-n参数后,则只有经过sed特殊处理的那一行(或者动作)才会被列出来。
32 |
33 | -e:直接在命令行模式上进行sed的动作编辑;
34 |
35 | -f:直接将sed的动作命令写在一个档案内,-ffilename则可以执行filename内的sed动作;
36 |
37 | -r:sed动作支持的是拓展正规表示法的语法(默认基础正规表示法语法)。
38 |
39 | -i:直接修改读取的档案内容,而不是由屏幕输出。
40 |
41 | 动作命令:
42 |
43 | a:新增,a后可以接字串,这些字串会在新一行出现(目前的下一行);
44 |
45 | c:替换,c的后面可以接字串,这些字串可以取代n1、n2之间的行!
46 |
47 | d:删除,因为是删除啊,所以d 后面通常不接任何东西;
48 |
49 | g:全局,表示动作命令在行内全局执行,也即如果行内有多个关键字,全部删除或替换;
50 |
51 | i:新增,i后可以接字串,这些字串会在新一行出现(目前的上一行);
52 |
53 | p:打印,亦即将某个选择的资料印出,通常p会与参数sed-n一起运行;
54 |
55 | s:替换,可以直接进行替换的工作,通常s的动作可以搭配正则表达式。
56 |
57 | ### ⑴新增与删除功能
58 |
59 | sed可以以行为单位按照行号进行删除,例如列出文件内容打印行号并删除第2-5行:
60 |
61 | 
62 |
63 | 可以看到标准输出的内容少了2-5行,最后一行可以使用“$”代指。这里省略了-e,也即默认就是在命令行模式,还可以根据关键字进行删除,例如删除含有“CHEN”的行:
64 |
65 | 
66 |
67 | 但是这时文件的内容并没有被更改,如要是删除原文件的内容并保存,可以使用-i参数直接对文件执行命令:
68 |
69 | 
70 |
71 | 注意这时候虽然前三行被删去,行号仍是第一行开始,因为这里nl处理的是文件而不是标准输出内容。接下来我们新增新行内容,示例如下:
72 |
73 | 
74 |
75 | 
76 |
77 | 这时很明显的看出两个新增命令a和i的区别。可以使用“\+回车”来增添多行内容,示例如下:
78 |
79 | 
80 |
81 | ### ⑵替换与显示功能
82 |
83 | sed中的动作命令p可以根据行号显示内容,例如选择显示文件中的第5-7行内容:
84 |
85 | 
86 |
87 | sed中的动作命令c可以进行整行内容替换,例如将文件第2-4行重复内容替换为“reduplicates”:
88 |
89 | 
90 |
91 | sed中的动作命令s可以以行为单位查找关键字并进行替换,其中要查找的关键字可以搭配正则表达式进行,例如将文件中所有的“:”替换为“;”:
92 |
93 | 
94 |
95 | 其中g表示全局,也即每一行进行全部替换,若不加g则只替换找到的第一个关键字:
96 |
97 | 
98 |
99 | sed还可以直接处理文件,在多文库数据处理时,遇到重复barcode的情况,常需要进行barcode替换,如下所示:
100 |
101 | 
102 |
103 | 上面的例子中第一条表示将替换结果保存为新的文件,而后面两条则进行原文件直接修改。其中“^”表示只替换行首出现的关键字。
104 |
105 |
--------------------------------------------------------------------------------
/Linux04:三种软件安装方式及服务器基本环境搭建.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/aMJeiQW5z5FzeEdsRn44vA
2 |
3 |
4 |
5 |
6 |
7 | # Linux04:三种软件安装方式及服务器基本环境搭建
8 |
9 |
10 |
11 | 环境安装
12 |
13 |
14 |
15 | ### jdk安装(rpm安装)
16 |
17 | 1、rpm下载地址http://www.oracle.com/technetwork/java/javase/downloads/index.html
18 |
19 | 2、如果有安装openjdk 则卸载
20 |
21 | ```
22 | [root@kuangshen ~]# java -version
23 | java version "1.8.0_121"
24 | Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
25 | Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
26 | # 检查
27 | [root@kuangshen ~]# rpm -qa|grep jdk
28 | jdk1.8.0_121-1.8.0_121-fcs.x86_64
29 | # 卸载 -e --nodeps 强制删除
30 | [root@kuangshen ~]# rpm -e --nodeps jdk1.8.0_121-1.8.0_121-fcs.x86_64
31 | [root@kuangshen ~]# java -version
32 | -bash: /usr/bin/java: No such file or directory # OK
33 | ```
34 |
35 | 3、安装JDK
36 |
37 | ```
38 | # 安装java rpm
39 | [root@kuangshen kuangshen]# rpm -ivh jdk-8u221-linux-x64.rpm
40 |
41 | # 安装完成后配置环境变量 文件:/etc/profile
42 | JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
43 | CLASSPATH=%JAVA_HOME%/lib:%JAVA_HOME%/jre/lib
44 | PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
45 | export PATH CLASSPATH JAVA_HOME
46 | # 保存退出
47 |
48 | # 让新增的环境变量生效!
49 | source /etc/profile
50 |
51 | # 测试 java -version
52 | [root@kuangshen java]# java -version
53 | java version "1.8.0_221"
54 | Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
55 | Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
56 | ```
57 |
58 |
59 |
60 | ### Tomcat安装(解压缩安装)
61 |
62 | 1、安装好了Java环境后我们可以测试下Tomcat!准备好Tomcat的安装包!
63 |
64 | 2、将文件移动到/usr/tomcat/下,并解压!
65 |
66 | ```
67 | [root@kuangshen kuangshen]# mv apache-tomcat-9.0.22.tar.gz /usr
68 | [root@kuangshen kuangshen]# cd /usr
69 | [root@kuangshen usr]# ls
70 | apache-tomcat-9.0.22.tar.gz
71 | [root@kuangshen usr]# tar -zxvf apache-tomcat-9.0.22.tar.gz # 解压
72 | ```
73 |
74 | 3、运行Tomcat,进入bin目录,和我们以前在Windows下看的都是一样的
75 |
76 | ```
77 | # 执行:startup.sh -->启动tomcat
78 | # 执行:shutdown.sh -->关闭tomcat
79 | ./startup.sh
80 | ./shutdown.sh
81 | ```
82 |
83 | 4、确保Linux的防火墙端口是开启的,如果是阿里云,需要保证阿里云的安全组策略是开放的!
84 |
85 | ```
86 | # 查看firewall服务状态
87 | systemctl status firewalld
88 |
89 | # 开启、重启、关闭、firewalld.service服务
90 | # 开启
91 | service firewalld start
92 | # 重启
93 | service firewalld restart
94 | # 关闭
95 | service firewalld stop
96 |
97 | # 查看防火墙规则
98 | firewall-cmd --list-all # 查看全部信息
99 | firewall-cmd --list-ports # 只看端口信息
100 |
101 | # 开启端口
102 | 开端口命令:firewall-cmd --zone=public --add-port=80/tcp --permanent
103 | 重启防火墙:systemctl restart firewalld.service
104 |
105 | 命令含义:
106 | --zone #作用域
107 | --add-port=80/tcp #添加端口,格式为:端口/通讯协议
108 | --permanent #永久生效,没有此参数重启后失效
109 | ```
110 |
111 |
112 |
113 | ### 安装Docker(yum安装)
114 |
115 | > 基于 CentOS 7 安装
116 |
117 | 1. 官网安装参考手册:https://docs.docker.com/install/linux/docker-ce/centos/
118 |
119 | 2. 确定你是CentOS7及以上版本
120 |
121 | ```
122 | [root@192 Desktop]# cat /etc/redhat-release
123 | CentOS Linux release 7.2.1511 (Core)
124 | ```
125 |
126 | 3. yum安装gcc相关(需要确保 虚拟机可以上外网 )
127 |
128 | ```
129 | yum -y install gcc
130 | yum -y install gcc-c++
131 | ```
132 |
133 | 4. 卸载旧版本
134 |
135 | ```
136 | yum -y remove docker docker-common docker-selinux docker-engine
137 | # 官网版本
138 | yum remove docker \
139 | docker-client \
140 | docker-client-latest \
141 | docker-common \
142 | docker-latest \
143 | docker-latest-logrotate \
144 | docker-logrotate \
145 | docker-engine
146 | ```
147 |
148 | 5. 安装需要的软件包
149 |
150 | ```
151 | yum install -y yum-utils device-mapper-persistent-data lvm2
152 | ```
153 |
154 | 6. 设置stable镜像仓库
155 |
156 | ```
157 | # 错误
158 | yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
159 | ## 报错
160 | [Errno 14] curl#35 - TCP connection reset by peer
161 | [Errno 12] curl#35 - Timeout
162 |
163 | # 正确推荐使用国内的
164 | yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
165 | ```
166 |
167 | 7. 更新yum软件包索引
168 |
169 | ```
170 | yum makecache fast
171 | ```
172 |
173 | 8. 安装Docker CE
174 |
175 | ```
176 | yum -y install docker-ce docker-ce-cli containerd.io
177 | ```
178 |
179 | 9. 启动docker
180 |
181 | ```
182 | systemctl start docker
183 | ```
184 |
185 | 10. 测试
186 |
187 | ```
188 | docker version
189 |
190 | docker run hello-world
191 |
192 | docker images
193 | ```
194 |
195 |
196 |
197 | ### 宝塔面板安装
198 |
199 | https://www.bilibili.com/video/av91821322
200 |
201 |
202 |
203 | 说明:后面我们会在Linux搭建很多环境,每个环境的搭建留在每个对应的课程中去讲解、比如Redis、Kafka、Elasticsearch等等..... 这里大家只需要掌握基本的套路即可!
204 |
205 |
--------------------------------------------------------------------------------
/学编程,怎么能不懂正则表达式!.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/w5vlmMYsxC8cbvAiIqGZHQ
2 |
3 |
4 |
5 |
6 |
7 | # 学编程,怎么能不懂正则表达式!
8 |
9 |
10 |
11 | 
12 |
13 | 在数学中表达式由数字、运算符、分组符号也即括号和变量组成,由于变量的存在我们可以使用数学表达式对数值信息进行批量云算,从而高效的完成各种计算任务。同样的,批量处理文本信息我们也需要借助表达式以及起变量作用的特殊符号,这种表达式我们称之为正则表达式。正则表达式应用广泛,在很多计算机语言中都有涉及,今天主要带大家学习Bash中的正则表达式及其使用方法。
14 |
15 | 
16 |
17 |
18 |
19 | 正则表达式,又称规则表达式(regularexpression,RE)通过一些特殊字符的排列用于查找、替换、删除符合某个模式(规则)的文本,是一种文本文件字符串处理的标准依据(一定要与通配符区分开,通配符主要用于文件管理)。很多工具命令以及软件都支持正则表达式,例如前面介绍的vim、grep以及后续要介绍的sed、awk等。许多程序设计语言也都支持利用正则表达式进行字符串操作,例如在Perl语言中就内建了一个功能强大的正则表达式引擎。因此,正则表达式对于处理文本数据非常重要。
20 |
21 | 接下来我们循序渐进,使用grep学习常用正则表达式的用法(一般使用LANG=C),可以使用下列命令:
22 |
23 | ```
24 | wget http://linux.vbird.org/linux_basic/0330regularex/regular_express.txtsed -i 's/^M//' regular_express.txt#注意,上面命令中的^M输入方法为先Ctrl+V后Ctrl+M
25 | ```
26 |
27 | 来获取练习数据,该文件如下所示:
28 |
29 | ```
30 | "Open Source" is a good mechanism to develop programs.apple is my favorite food.Football game is not use feet only.this dress doesn't fit me.However, this dress is about $ 3183 dollars.GNU is free air not free beer.Her hair is very beauty.I can't finish the test.Oh! The soup taste good.motorcycle is cheap than car.This window is clear.the symbol '*' is represented as start.Oh! My god!The gd software is a library for drafting programs.You are the best is mean you are the no. 1.The world is the same with "glad".I like dog.google is the best tools for search keyword.goooooogle yes!go! go! Let's go.# I am VBird
31 | ```
32 |
33 | #### ⑴集合字符[]
34 |
35 | 在高级搜索中,常用中括号[]来集合字符,例如若想同时搜索test和taste这两个关键词,可以使用t[ae]st:
36 |
37 | 
38 |
39 | 搜索含有oo但前面不是g(也即去除goo)的行:
40 |
41 | 
42 |
43 | 搜索含有oo但前面不是小写字母的行:
44 |
45 | 
46 |
47 | 在正则表达式中,所有连续的字符组均可以这样表达,例如[a-z]、[A-Z]、[0-9],如果不是在C语系中,可以使用[:lower:]、[:upper]、[:digit:]分别代表小写字母、大写字母、数字:
48 |
49 | 
50 |
51 | #### ⑵行首行尾字符^$
52 |
53 | 字符^可以限定行首,而$可以限定行尾,例如要筛选行首为the的行(忽略大小写):
54 |
55 | 
56 |
57 | 筛选行首不是字母的行:
58 |
59 | 
60 |
61 | 要注意上面两个^含义是不同的。筛选行尾是r.的行:
62 |
63 | 
64 |
65 | 因为正则表达式中“**.**”具有特殊意义,所以需要“\”来转义。为了节省屏幕空间,去除空白行和行首为#的注释行:
66 |
67 | 
68 |
69 | #### ⑶任意字符.与重复字符*
70 |
71 | 与通配符不同,在正则表达式中.代表一个任意字符,而*代表重复前一个0到无穷多次,例如我们想查找含有g??d的行:
72 |
73 | 
74 |
75 | 筛选至少含有两个o的行:
76 |
77 | 
78 |
79 | 利用重复字符可以表示任意字符“.*”,例如筛选g开头与g结尾的字符串,中间字符可有可无:
80 |
81 | 
82 |
83 | 筛选含有任意数字的行:
84 |
85 | 
86 |
87 | #### ⑷限定连续字符范围{}
88 |
89 | 在正则表达式中{}可以用来界定连续字符的范围,但是由于在shell中{}具有特殊意义(数组引用),因此需要“\”来进行转义,例如筛选含有2个o的字符串:
90 |
91 | 
92 |
93 | 查找g后面接2-6个o,然后再接一个g的字符串:
94 |
95 | 
96 |
97 | 学会正则表达式的使用后,我们就可以进一步学习sed、awk等文本处理的工具了。
98 |
99 |
--------------------------------------------------------------------------------
/Linux系统入门系列之二.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/lHzsdtpjYiGm2diy33gC6g
2 |
3 |
4 |
5 | # Linux系统入门系列之二
6 |
7 |
8 |
9 | ### 3命令管理
10 |
11 | #### 3.1命令连接符
12 |
13 | 当需要一次执行多个命令的时候,可以同时输入,不同命令之间可以使用分号“;”隔开,示例如下:
14 |
15 | 
16 |
17 | 上面的多命令之间是独立的,按照先后顺序执行,多个相互依赖的命令之间还可以通过逻辑连接符“&&”和“||”来连接,具体如下:
18 |
19 | cmd1&& cmd2:若cmd1执行正确则开始执行cmd2,否则不执行;
20 |
21 | cmd1|| cmd2:若cmd1执行正确则不执行cmd2,否则执行。
22 |
23 | 具体示例如下:
24 |
25 | 
26 |
27 |
28 |
29 | #### 3.2管道命令
30 |
31 | 管道命令(pipe)是由多个命令组成的定向处理流程,但与命令的连续执行或判断执行不同,后续命令仅能处理前面命令传来的正确信息,不同命令间使用“|”界定。
32 |
33 | 例如,我们列出etc下的所有文件,并将结果进行分页展示,示例如下:
34 |
35 | 
36 |
37 | 查询服务器用户登录信息,并将“tengwk”用户的信息选取出来,并剪取用户名和登录时间:
38 |
39 | 
40 |
41 | 命令:xargs
42 |
43 | 该命令可以使不支持管道命令的指令引用标准输入内容,使用示例如下:
44 |
45 | 
46 |
47 | 命令ls -l只能作用于文件和路径,并不能处理标准输入的内容,也即不支持管道命令,因此会将所有文件列出。然而xargs可以将标准输入的内容转换为指令的作用对象。该命令还可以产生命令的参数,例如-p可以提醒后面命令的意义,用户可以输入y(yes)或n(no)来选择是否执行:
48 |
49 | 
50 |
51 | xargs具体参数如下:
52 |
53 | -n后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的;
54 |
55 | -P修改最大的进程数(也即一次提交的最大任务数),默认是1;
56 |
57 | -i或者是-I,将xargs的参数的每项名称,一般是一行一行赋值给{},可以用{}代替,例如:ls *.out | xargs -i mv {} {}.txt。
58 |
59 |
60 |
61 | #### 3.3软件脚本
62 |
63 | 在Linux中,可以使用命令充分调用各种软件(脚本)来完成分析任务,也可以将Linux命令整合为shell脚本,这样便于管理与修改。
64 |
65 | 命令:perl
66 |
67 | 在Linux中调用perl脚本并输出结果,示例如下:
68 |
69 | perl perl02.pl
70 |
71 | 命令:Rscript
72 |
73 | 在Linux中调用perl脚本并输出结果,示例如下:
74 |
75 | Rscript r01.R
76 |
77 | 命令:sh
78 |
79 | 执行多命令整合成shell脚本,示例如下:
80 |
81 | 
82 |
83 | 对于安装的软件,调用时则需要完整的绝对路径,例如Mothur,需要输入/sdd/userLogin/zhengjw/softwares/mothur/mothur然后回车来输入命令,或者直接输入命令,示例如下:
84 |
85 | 
86 |
87 | 对于经常用到的软件,我们可以将其路径添加到环境变量PATH,则可以直接调用,首先我们需要修改用户主目录下的配置文件,示例如下:
88 |
89 | 
90 |
91 | 最后执行source激活环境变量:
92 |
93 | source ~/.bashrc
94 |
95 | 这时候便可以直接调用mothur:
96 |
97 | 
98 |
99 |
100 |
101 | #### 3.4任务管理
102 |
103 | 命令:nohup……&
104 |
105 | 表示命令无间断的后台运行,示例如下:
106 |
107 | 
108 |
109 | 命令:jobs
110 |
111 | 查看当前用户当前窗口正在运行的脚本程序,示例如下:
112 |
113 | 
114 |
115 | 命令:ps
116 |
117 | 列出当前用户正在运行的程序,示例如下:
118 |
119 | 
120 |
121 | 列出正在运行的程序及其完整路径:
122 |
123 | 
124 |
125 | 参数选项含义如下:
126 |
127 | u:与当前用户相关的进程;
128 |
129 | x:通常与a参数一起使用,可列出较完整信息(包括程序执行路径);
130 |
131 | f:按照程序运行时间进行排序。
132 |
133 | 注意这个命令参数选项前不需要加“-”。
134 |
135 | 命令:kill
136 |
137 | 结束当前正在运行的某个程序,示例如下:
138 |
139 | kill PID
140 |
141 | kill %程序编号
142 |
143 | 其中%后面跟的是jobs查看的程序编号,示例如下:
144 |
145 | 
146 |
147 | 命令:top
148 |
149 | 动态显示显示当前系统正在执行的进程的相关信息,包括进程ID、内存占用率、CPU占用率等,示例如下:
150 |
151 | 
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/How To Build Lightweight Docker Images With Mmdebstrap In Linux.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://ostechnix.com/build-docker-images-with-mmdebstrap/
2 |
3 |
4 |
5 | # How To Build Lightweight Docker Images With Mmdebstrap In Linux
6 |
7 | ## A Step-by-Step Guide to Create Minimal Debian-based Container Images for Docker using Mmdebstrap
8 |
9 |
10 |
11 | Building lightweight container images with **`mmdebstrap`** for **[Docker](https://ostechnix.com/getting-started-with-docker/)** is a great way to create minimal and efficient environments for your applications. This process allows you to leverage the power of Debian while keeping your images small and manageable. In this step-by-step tutorial, we will explain how to **build docker images with mmdebstrap** in Linux.
12 |
13 | This is useful to create optimized, minimal Docker images, such as microservices, CI/CD pipelines, or serverless applications.
14 |
15 |
16 |
17 | ## **Why Use `mmdebstrap`?**
18 |
19 | - **Small Base Images:** It produces minimal Debian root filesystems, reducing image size.
20 | - **Flexible Output Formats:** It can generate tarballs, squashfs, or directory outputs, which can be easily imported into Docker.
21 | - **No Dependencies:** It does not require `dpkg` or `apt` inside the container.
22 | - **Reproducibility:** It supports exact package versions for consistent builds.
23 |
24 |
25 |
26 | ## Build Docker Images with mmdebstrap
27 |
28 | **`mmdebstrap`** is a modern, minimal, and dependency-free alternative to `debootstrap` for creating Debian-based root filesystems. It supports reproducible builds and integrates well with Docker.
29 |
30 | ### Prerequisites
31 |
32 | Before you start, ensure you have the following installed:
33 |
34 | Make sure **Docker is installed** and running on your system. if not, use the following links to install Docker on your preferred Linux system.
35 |
36 | - **[Install Docker Engine And Docker Compose In RPM-based Systems](https://ostechnix.com/install-docker-almalinux-centos-rocky-linux/)**
37 | - **[How to Install Docker Engine And Docker Compose In Ubuntu](https://ostechnix.com/install-docker-ubuntu/)**
38 |
39 | You can also use **[Podman](https://ostechnix.com/what-is-podman-and-how-to-install-podman-in-linux/)** if you prefer to run containers in rootless mode.
40 |
41 |
42 |
43 | Next, **[Install mmdebstrap](https://ostechnix.com/create-chroot-environments-using-mmdebstrap-in-debian-linux/)** if you haven't already. You can do this with the following command:
44 |
45 | ```
46 | sudo apt update
47 | sudo apt install mmdebstrap
48 | ```
49 |
50 | ### Step 1: Create a Minimal Debian Filesystem
51 |
52 | We will first create a basic Debian image using `mmdebstrap`. This image will serve as the foundation for our Docker container.
53 |
54 | **1. Choose a Debian Suite**:
55 |
56 | Decide which Debian release you want to use (e.g., `bullseye`, `bookworm`).
57 |
58 | **2. Create the Image**:
59 |
60 | Run the following command to create a basic Debian filesystem:
61 |
62 | ```
63 | mmdebstrap --variant=minbase --include=ca-certificates,curl stable debian-rootfs.tar
64 | ```
65 |
66 | This adds required packages like `curl` and `ca-certificates`. You can further customize the container by installing any other additional packages or making configuration changes.
67 |
68 | Here,
69 |
70 | - **`--variant=minbase`:** Creates a minimal base system without unnecessary packages.
71 | - **`--include=ca-certificates,curl`**: Installs curl and ca-certificates in the debian image.
72 | - **`stable`:** Specifies the Debian release (e.g., `stable`, `bookworm`, or `bullseye`).
73 | - **`debian-rootfs.tar`:** Output tarball for the root filesystem.
74 |
75 | You can also clean up package caches and logs inside the tarball before importing:
76 |
77 |
78 |
79 | ```
80 | tar --delete -f debian-rootfs.tar ./var/cache/apt ./var/lib/apt/lists
81 | ```
82 |
83 | ### Step 2: Import the Tarball into Docker
84 |
85 | Import the Debian image that you created in the earlier step into docker using command:
86 |
87 | ```
88 | cat debian-rootfs.tar | docker import - debian:custom
89 | ```
90 |
91 | Here,
92 |
93 | - **`debian:custom`:** Assigns a tag to the imported image.
94 |
95 | ### Step 3: Verify the Docker Images
96 |
97 | Verify if the docker image is imported into your docker environment using command:
98 |
99 | ```
100 | docker images
101 | ```
102 |
103 | You will see an output like below:
104 |
105 | ```
106 | REPOSITORY TAG IMAGE ID CREATED SIZE
107 | localhost/debian custom 7762908acf49 21 seconds ago 170 MB
108 | ```
109 |
110 | ### Step 4: Run the Container
111 |
112 | Finally, run the container with the new image using command:
113 |
114 |
115 |
116 | ```
117 | docker run -it debian:custom /bin/bash
118 | ```
119 |
120 | This command starts a new container from your image and opens an interactive terminal.
121 |
122 | If you want to run the container in detached mode, use `-d` flag.
123 |
124 | ## Conclusion
125 |
126 | Using `mmdebstrap` to build lightweight container images for Docker is a straightforward process. By creating a minimal Debian environment, you can ensure that your images are small and efficient.
127 |
128 | This method is especially useful for developers looking to create custom Docker images tailored to their applications. With just a few steps, you can have a fully functional and lightweight Debian container ready for your projects.
129 |
130 | **Related Read**:
131 |
132 | - **[How To Build Custom Docker Image Using Dockerfile](https://ostechnix.com/a-brief-introduction-to-dockerfile/)**
133 | - **[Troubleshooting Guide For Mmdebstrap: Fixing Common Issues](https://ostechnix.com/troubleshooting-mmdebstrap/)**
134 |
135 |
--------------------------------------------------------------------------------
/Linux系统入门系列之四:工具命令.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/nq4wK0uXnDY7rhYxqCqK9Q
2 |
3 |
4 |
5 |
6 |
7 | # Linux系统入门系列之四:工具命令
8 |
9 |
10 |
11 | 
12 |
13 | 
14 |
15 | 在上一篇文章[Linux系统入门系列之三:初识Bash](https://mp.weixin.qq.com/s?__biz=Mzg3MzEwMzIwOA==&mid=2247483985&idx=1&sn=968cc499d2aa29c3f46bf4a0e9db6eda&scene=21#wechat_redirect)中,我带大家初步认识了Bash这个Linux系统中的Shell,并学习了使用vim编辑、处理文本信息。事实上Bash拥有非常多的工具命令,并且很多工具命令已经集成化,可以完成多种多样的任务,就像Windows系统中的Office软件一样。接下来将带大家认识更多的工具命令以及数据的输入与输出,从而便以后各种生物信息数据的处理。
16 |
17 | ——走进Bash
18 |
19 | ## 3.工具命令
20 |
21 | 虽然Vim很强大,但是批量处理一些文本文档尤其是很大的文件(例如高通量测序数据),一些逐行处理的工具命令非常实用。
22 |
23 | ### ⑴选取命令:cut,grep
24 |
25 | 选取命令可以基于关键字按行搜索,将含有关键字的行选取出来。一般来说cut为剪取(注意不是剪去)标准输出的内容(可以理解为屏幕显示内容,可以来自cat/more/less),而grep除了处理标准输出的内容还可以处理文件,使用规则如下:
26 |
27 | ```
28 | cut -d ‘分割字符’ -f ‘范围’cut -c ‘字符范围’grep -acinvw --color=auto ‘要选取的内容’ ‘文件名称’
29 | ```
30 |
31 | 其中grep参数-i忽略大小写,-v反向选取,-n输出行号,-w匹配整个单词。**注意,有时候工具命令里的单引号和双引号不能相互替代!**使用示例如下:
32 |
33 | 
34 |
35 | --color=auto将关键字使用其他颜色标识:
36 |
37 | 
38 |
39 |
40 |
41 | ### ⑵排序命令:sort,uniq,wc
42 |
43 | sort可以依据数据类型来进行排序,uniq可以合并相同数据类型并计算数目,wc可以计算文件的字符数、行数等信息,使用规则如下:
44 |
45 | ```
46 | sort -bfMnrtuk ‘文件或标准输出’
47 | ```
48 |
49 | 其中-f忽略大小写,-b忽略最前面空格,-M按月份排序,-n纯数字排序,-r反向排序,-u相同数据拍在同一行,-t分隔符类型,默认为空格(若是tab需要转义:-t $'\t'),-k作为排序标准的区间,默认以行首排序。
50 |
51 | ```
52 | uniq -ic
53 | ```
54 |
55 | 其中-i为忽略大小写,-c为对相同数据进行计数。
56 |
57 | ```
58 | wc -lwm ‘文件或标准输出’
59 | ```
60 |
61 | 其中-l列出行数,-w列出字数,-m列出字符数,排序计数的具体使用示例如下:
62 |
63 | 
64 |
65 | 计算文件的整体数据:
66 |
67 | 
68 |
69 | 需要注意的是,不同语系下排序顺序不同,例如在en_US.UTF-8中,字母无论大小写均按照字母表顺序排序,而C语言中大写字母排在小写字母之前:
70 |
71 | 
72 |
73 |
74 |
75 | 
76 |
77 | 计算当前路径下文件数目:
78 |
79 | 
80 |
81 |
82 |
83 | ### ⑶字符转换命令:tr,col,expand
84 |
85 | 命令tr可以删除或替换文字信息,col和expand可以将tab键转换为空格键,使用规则如下:
86 |
87 | ```
88 | tr -ds ‘要删除的内容’ ‘要替换的内容’
89 | ```
90 |
91 | 命令tr可以处理来自标准输出的内容,其中-d为删除,-s为替换,例如将“:”替换为“;”方法示例如下:
92 |
93 | 
94 |
95 | 将所有的小写字母替换为大写字母并保存:
96 |
97 | 
98 |
99 |
100 |
101 | ```
102 | col -x
103 | ```
104 |
105 | 命令col可以处理标准输出的内容,其中-x将tab键转换为对等的空格键。使用示例如下:
106 |
107 | 
108 |
109 |
110 |
111 | ```
112 | expand -t
113 | ```
114 |
115 | 命令expand可以处理标准输出内容,其中-t后面跟数字,一般一个tab键可以用8个空格键替换。使用示例如下:
116 |
117 | 
118 |
119 |
120 |
121 | ### ⑷整合切割命令:join,paste,split
122 |
123 | 命令join可以将具有相同数据的两个文件整合到一起,命令paste将两个文件的行并列并以tab分隔,命令split可以将大文件根据大小或行数切割成小文件以便于复制。使用规则如下:
124 |
125 | ```
126 | join -ti12 file1 file2
127 | ```
128 |
129 | 命令join可以处理文件内容并转换为标准输出,其中-t后面跟分隔符,默认是空格或tab,-i忽略大小写,-1后面跟数字,也即第一个文件以一行的第几个字段为关键字,默认为行首,-2也即第二个文件以一行的第几个字段为关键字。使用示例如下:
130 |
131 | 
132 |
133 |
134 |
135 | ```
136 | paste -d file1 file2
137 | ```
138 |
139 | 命令paste可以按行将两个文件整合为一个文件,而不需要按照关键字。其中-d后面为分隔符,默认为tab。使用示例如下:
140 |
141 | 
142 |
143 |
144 |
145 | ```
146 | split -bl file sfile
147 | ```
148 |
149 | 命令split可以直接切割文件数据,其中-b后面加要切割成的文件大小,可以直接写字节数或者加k、m单位,-l后面加要切割成的文件行数,sfile为小文件前导名,命令会自动加后缀区分,使用示例如下:
150 |
151 | 
152 |
153 |
--------------------------------------------------------------------------------
/10个POSIX编程的代码示例.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # POSIX编程的代码示例
4 |
5 |
6 |
7 | 以下是10个Linux POSIX编程的代码示例,涵盖了线程、进程间通信和文件操作等多个方面。每个示例都附带简要说明。
8 |
9 | ### 1. 创建线程
10 |
11 | ```
12 | #include
13 | #include
14 |
15 | void* threadFunction(void* arg) {
16 | printf("Hello from thread!\n");
17 | return NULL;
18 | }
19 |
20 | int main() {
21 | pthread_t thread;
22 | pthread_create(&thread, NULL, threadFunction, NULL);
23 | pthread_join(thread, NULL);
24 | return 0;
25 | }
26 | ```
27 |
28 | ### 2. 使用信号量
29 |
30 | ```
31 | #include
32 | #include
33 | #include
34 |
35 | sem_t semaphore;
36 |
37 | void* worker(void* arg) {
38 | sem_wait(&semaphore);
39 | printf("In critical section\n");
40 | sem_post(&semaphore);
41 | return NULL;
42 | }
43 |
44 | int main() {
45 | pthread_t thread1, thread2;
46 | sem_init(&semaphore, 0, 1);
47 |
48 | pthread_create(&thread1, NULL, worker, NULL);
49 | pthread_create(&thread2, NULL, worker, NULL);
50 |
51 | pthread_join(thread1, NULL);
52 | pthread_join(thread2, NULL);
53 |
54 | sem_destroy(&semaphore);
55 |
56 | return 0;
57 | }
58 | ```
59 |
60 | ### 3. 条件变量
61 |
62 | ```
63 | #include
64 | #include
65 |
66 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
67 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
68 |
69 | void* producer(void* arg) {
70 | // produce something
71 | pthread_cond_signal(&cond);
72 | return NULL;
73 | }
74 |
75 | void* consumer(void* arg) {
76 | pthread_cond_wait(&cond, &mutex);
77 | printf("Consumed an item\n");
78 | return NULL;
79 | }
80 |
81 | int main() {
82 | pthread_t p_thread, c_thread;
83 |
84 | pthread_create(&p_thread, NULL, producer, NULL);
85 | pthread_create(&c_thread, NULL, consumer, NULL);
86 |
87 | pthread_join(p_thread, NULL);
88 | pthread_join(c_thread,NULL);
89 |
90 | return 0;
91 | }
92 | ```
93 |
94 | ### 4. 使用共享内存
95 |
96 | ```
97 | #include
98 | #include
99 | #include
100 | #include
101 |
102 | int main() {
103 | int fd = shm_open("/my_shm", O_CREAT | O_RDWR | O_EXCL , S_IRUSR | S_IWUSR);
104 |
105 | // Set size of shared memory object
106 | ftruncate(fd , sizeof(int));
107 |
108 | int *ptr = mmap(0,sizeof(int),PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 );
109 |
110 | *ptr = 42; // Write to shared memory
111 |
112 | munmap(ptr , sizeof(int));
113 | close(fd);
114 | shm_unlink("/my_shm"); // Clean up
115 |
116 | return 0;
117 | }
118 | ```
119 |
120 | ### 5. 管道示例
121 |
122 | ```
123 | #include
124 | #include
125 |
126 | int main() {
127 | int fd[2];
128 | pipe(fd);
129 |
130 | if (fork() == 0) { // Child process
131 | close(fd[1]); // Close writing end in child.
132 | char buffer[20];
133 | read(fd[0], buffer , sizeof(buffer));
134 | printf("Child received: %s\n", buffer);
135 | } else { // Parent process
136 | close(fd[0]); // Close reading end in parent.
137 | const char *msg = "Hello from parent!";
138 | write(fd[1], msg , strlen(msg)+1);
139 | }
140 |
141 | return 0;
142 | }
143 | ```
144 |
145 | ### 6. 文件I/O操作示例
146 |
147 | ```
148 | #include
149 | #include
150 | #include
151 |
152 | int main() {
153 | int fd = open("example.txt", O_CREAT | O_WRONLY | O_TRUNC , S_IRUSR | S_IWUSR);
154 |
155 | const char *text = "Hello POSIX!";
156 | write(fd , text , strlen(text));
157 |
158 | close(fd);
159 | return 0;
160 | }
161 | ```
162 |
163 | ### 7. 定时器使用示例
164 |
165 | ```
166 | #define _POSIX_C_SOURCE 199309L
167 |
168 | #include
169 | #include
170 | #include
171 |
172 | void timer_handler(int signum) {
173 | printf("Timer expired!\n");
174 | }
175 |
176 | int main() {
177 | struct sigaction sa;
178 | struct itimerspec timer;
179 |
180 | sa.sa_handler = timer_handler;
181 | sigaction(SIGRTMIN + 1,&sa,NULL);
182 |
183 | timer.it_value.tv_sec = 2; // First expiration after two seconds.
184 | timer.it_value.tv_nsec = 0;
185 | timer.it_interval.tv_sec = 2; // Subsequent expiration every two seconds.
186 | timer.it_interval.tv_nsec = 0;
187 |
188 | timer_settime(timerid , TIMER_ABSOLUTE &timer );
189 |
190 | while(1){ /* Do other work */ }
191 |
192 | return(0);
193 | }
194 | ```
195 |
196 | ### 8. 消息队列示例(System V)
197 |
198 | ```
199 | #include
200 | #include
201 | #define MSG_SIZE sizeof(struct msgbuf)-sizeof(long)
202 |
203 | struct msgbuf{
204 | long mtype;
205 | char mtext[100];
206 | };
207 |
208 | int main()
209 | {
210 | int msqid=msgget(IPC_PRIVATE|0666|IPC_CREAT);
211 | struct msgbuf message;
212 |
213 | message.mtype=1;
214 | strcpy(message.mtext,"hello world");
215 |
216 | msgsnd(msqid,&message,msg_size(),IPC_NOWAIT);
217 |
218 | msgrcv(msqid,&message,msg_size(),msgtype(1),MSG_NOERROR);
219 |
220 |
221 | return(0);
222 | }
223 | ```
224 |
225 | ### 9. fork 示例程序:
226 |
227 | ```
228 | #include
229 | #include
230 |
231 | int main (){
232 | pid_t pid=fork();
233 |
234 | if(pid== -1 ){
235 | perror ("Error forking");
236 | }else if(pid== 0 ){
237 | printf ("Child Process ID: %d \n ",getpid());
238 | }else{
239 | printf ("Parent Process ID: %d \n ",getpid());
240 | wait(NULL );
241 | }
242 |
243 | return (EXIT_SUCCESS );
244 | }
245 | ```
246 |
247 | ### 10. 获取当前进程ID和父进程ID:
248 |
249 | ```
250 | #include
251 |
252 | int main (){
253 |
254 | pid_t pid=getpid ();
255 | pid_t ppid=getppid ();
256 |
257 | printf ("Current Process ID : %d \n ",pid );
258 | printf ("Parent Process ID : %d \n ",ppid );
259 |
260 | return (EXIT_SUCCESS );
261 | }
262 | ```
263 |
264 | 以上代码展示了不同的POSIX编程技巧,你可以根据需要进行扩展和修改。确保在适合的环境中测试这些代码,并检查相关头文件及库的依赖。希望这些对你学习POSIX编程有所帮助!
265 |
266 |
--------------------------------------------------------------------------------
/awk:强大的文本分析工具.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/3ox5JSC80_2eOMV60Hxtfw
2 |
3 |
4 |
5 |
6 |
7 | # awk:强大的文本分析工具
8 |
9 |
10 |
11 | 
12 |
13 |
14 |
15 | awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格或tab为默认分隔符将每行切片,切开的部分再进行各种分析处理。awk可以处理文件数据,或者来自前个命令的标准输入内容,awk的一般使用规则如下:
16 |
17 | ```
18 | awk -Ffv 'BEGIN{} //条件{动作1;动作2} END {}' 文件或标准输入
19 | ```
20 |
21 | 大参数:参数-F指定分隔符,-f调用脚本,-v定义变量;
22 |
23 | BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
24 |
25 | // 匹配代模块,可以是字符串或正则表达式
26 |
27 | {} 命令代模块,包含一条或多条命令
28 |
29 | ; 多条命令使用分号分隔
30 |
31 | END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
32 |
33 | ### 01数据内容选取
34 |
35 |
36 |
37 |
38 |
39 | 我们可以使用匹配模块搭配正则表达式选取行:
40 |
41 | 
42 |
43 | 其中匹配内容里面可以使用bash变量,但是必须用加单引号,如下所示:
44 |
45 | 
46 |
47 | 我们也可以根据分隔符选取字段,例如使用last列出最后五行登陆者信息,并使用awk中print命令选取账户名及其IP信息:
48 |
49 | 
50 |
51 | 其中“\t”表示分隔符为tab,注意这里是打印内容的分隔符,而不是划分域的分隔符,可以换成其他符号甚至是任意字符串(包括数据)均可:
52 |
53 | 
54 |
55 | 最后一行是时间信息,中间隔着一行空行,如要是进一步只选取账户和IP可以使用sed命令:
56 |
57 | 
58 |
59 | 由以上例子可以看出awk工作流程:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是空格键或[tab]键,所以$1表示登录用户,$3表示登录用户IP,也即awk是以行为一次处理单位,域(字段)为最小的处理单元。
60 |
61 | 可以使用-F强制制定其他划分域的分隔符,多个分隔符使用[]括起来:
62 |
63 | 
64 |
65 | 这里需要注意"/:"和"[/:]"的不同。这个功能在处理物种分类信息的时候非常有用,例如多样性分析中otutable的物种注释信息各个水平堆叠在一起,不利于作图:
66 |
67 | 
68 |
69 | 我们可以从中选取科水平的注释结果:
70 |
71 | 
72 |
73 | 提取的结果可以保存到文件:
74 |
75 | 
76 |
77 | 保存的文件可以安行和原来的otu table进行合并(使用paste命令)。
78 |
79 | ### 02内置变量
80 |
81 |
82 |
83 |
84 | awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量:
85 |
86 | ENVIRON 支持队列中系统环境变量的使用
87 |
88 | FILENAME awk浏览的文件名,对于批量处理文件很有用
89 |
90 | FNR 浏览文件的次数,一般与NR相同,**大于****NR****处理多个文件**
91 |
92 | FS 设置输入域分隔符,等价于命令行-F选项
93 |
94 | NF 浏览记录的域的个数
95 |
96 | NR 已读的记录数,**可以指定处理某一行**
97 |
98 | OFS 输出域分隔符
99 |
100 | ORS 输出记录分隔符
101 |
102 | RS 控制记录分隔符
103 |
104 | 下面我们利用内置变量来处理数据信息:
105 |
106 | 
107 |
108 | 在上面例子中,我们使用内置变量显示了行号以及每一行的字段数目。
109 |
110 | ### 03条件运算符
111 |
112 |
113 |
114 | awk的命令间也可以使用条件运算符设置条件类型,使得命令选择性执行,常见的有大于>、小于<、大于等于>=、小于等于<=、等于==、不等于!=、匹配~、不匹配!~。下面我们以/etc/passwd文件为例,这个文件每一行字段之间以“:”分割,如下所示:
115 |
116 | 
117 |
118 | 接下来我们选取第三个字段也即UID大于500小于600的数据行,并且列出每行第一字段账号和第三字段UID:
119 |
120 | 
121 |
122 | 可以发现,条件类型里还可以使用逻辑连接符。awk的这种数据筛选功能也非常有用,例如可以用来筛选高丰度的物种或者基因。
123 |
124 | ### 04AWK编程
125 |
126 |
127 |
128 |
129 |
130 | awk的条件类型决定着动作命令的执行,其条件语句可以通过变量以及判断语句进行编程实现,还可以搭配正则表达式。
131 |
132 | 除了awk自定义的变量,用户可以根据需要自定义变量,例如我们可以通过自定义变量计算文件的行数:
133 |
134 | 
135 |
136 | 在这里count=count+1可以简写为count+=1,或者count++,同理每次加2则表示为count+=2。上面命令的另一种写法为:
137 |
138 | ```
139 | awk 'BEGIN{count=0} {count=count+1} END{print "user count is ", count}' /etc/passwd
140 | ```
141 |
142 |
143 |
144 | awk同样可使用if控制结构,例如前面计算序列总数的命令使用if结构如下:
145 |
146 | 
147 |
148 | 要注意if() {} else {}是一个完整的结构,要放在一个花括号内。
149 |
150 | awk同样可以引入数组以及for结构。awk中的数组下标**可以是数字和字母**,数组的下标通常被称为关键字(key)。下面通过两个例子比较说明:
151 |
152 | ```
153 | ①awk -F ':' 'BEGIN{count=1} {name[count]=$1;count++} END{for (i=1; i<=NR; i++) print i, name[i]}' /etc/passwd②last -n 100 | sed -n '1,100p' | awk '{a[$1]++} END{for (i in a) print i,"\t", a[i]}'
154 | ```
155 |
156 | 第一个例子中,定义了name[count]数组,for为迭代循环,因为数组的下标是从1开始的整数,通过迭代打印出对应的下标以及数组内容。第二个例子中定义了关联数组a[$1](参照Perl语言中的哈希),其下标是key(既可能是数字也可能是字母,没有规则)不需要定义初值,通过for循环结构打印出结果。a[$1]++实质为计算$1中字符串的出现的次数,也即统计重复字符数,这里为统计最近100次登录里每个账号的登陆次数。需要注意的是,awk是通过一行行不断浏览文件的方法来执行命令,因此NR也是不断变化的,但是END后面的模块中NR为最后一次浏览完的数据。运行结果如下所示:
157 |
158 | 
159 |
160 | 
161 |
162 |
--------------------------------------------------------------------------------
/Posix多线程编程.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://cloud.tencent.com/developer/article/1457096
2 |
3 |
4 |
5 |
6 |
7 | # Posix多线程编程
8 |
9 |
10 |
11 | **一、线程与多线程的定义**
12 |
13 | 线程存在于进程当中,是操作系统调度执行的最小单位。说通俗点线程就是干活,多线程也就是同时可以干不同的活而且还不会互相打扰,线程并没有自己的独立空间。
14 |
15 | **二、进程与线程的区别与联系**
16 |
17 | 如果说进程是一个资源管家,负责从主人那里要资源的话,那么线程就是干活的苦力。
18 |
19 | 一个管家必须完成一项工作,就需要最少一个苦力,也就是说,一个进程最少包含一个线程,也可以包含多个线程。苦力要干活,就需要依托于管家,所以说一个线程,必须属于某一个进程。进程有自己的地址空间,线程使用进程的地址空间,也就是说,进程里的资源,线程都是有权访问的,比如说堆啊,栈啊,静态存储区什么的。
20 |
21 | 线程就是个无产阶级,但无产阶级干活,总得有自己的劳动工具吧,这个劳动工具就是栈,线程有自己的栈,这个栈仍然是使用进程的地址空间,只是这块空间被线程标记为了栈。每个线程都会有自己私有的栈,这个栈是不可以被其他线程所访问的。
22 |
23 | 从上面我们知道了进程和线程区别,使用多线程首先是要和进程相对比,它是一种非常便捷的多任务操作方式;我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。
24 |
25 | 线程操作相关的函数:
26 |
27 | **(1)线程创建函数**
28 |
29 | 代码语言:javascript
30 |
31 | 复制
32 |
33 | ```javascript
34 | 1int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
35 | ```
36 |
37 | 参数说明:
38 |
39 | pthread_create用于创建一个线程,成功返回0,否则返回Exxx(为正数)。
40 |
41 | pthread_t *tid:线程id的类型为pthread_t,通常为无符号整型,当调用pthread_create成功时,通过*tid指针返回。
42 |
43 | const pthread_attr_t *attr:指定创建线程的属性,如线程优先级、初始栈大小、是否为守护进程等。可以使用NULL来使用默认值,通常情况下我们都是使用默认值。
44 |
45 | void *(*func) (void *):函数指针func,指定当新的线程创建之后,将执行的函数。
46 |
47 | void *arg:线程将执行的函数的参数。如果想传递多个参数,请将它们封装在一个结构体中。
48 |
49 | **(2)线程等待的函数**
50 |
51 | 代码语言:javascript
52 |
53 | 复制
54 |
55 | ```javascript
56 | 1int pthread_join (pthread_t tid, void ** status);
57 | ```
58 |
59 | 参数说明:
60 |
61 | pthread_join用于等待某个线程退出,成功返回0,否则返回Exxx(为正数)。
62 |
63 | pthread_t tid:指定要等待的线程ID。
64 |
65 | void ** status:如果不为NULL,那么线程的返回值存储在status指向的空间中(这就是为什么status是二级指针的原因!这种才参数也称为“值-结果”参数)。
66 |
67 | **(3)获得线程自身的ID的函数**
68 |
69 | 代码语言:javascript
70 |
71 | 复制
72 |
73 | ```javascript
74 | 1pthread_t pthread_self (void);
75 | ```
76 |
77 | pthread_self用于返回当前线程的ID。
78 |
79 | **(4)线程分离的函数**
80 |
81 | 代码语言:javascript
82 |
83 | 复制
84 |
85 | ```javascript
86 | 1int pthread_detach (pthread_t tid);
87 | ```
88 |
89 | pthread_detach用于是指定线程变为分离状态,就像进程脱离终端而变为后台进程类似。成功返回0,否则返回Exxx(为正数)。变为分离状态的线程,如果线程退出,它的所有资源将全部释放。而如果不是分离状态,线程必须保留它的线程ID,退出状态直到其它线程对它调用了pthread_join。
90 |
91 | **(5)退出线程(终止线程)的函数**
92 |
93 | 代码语言:javascript
94 |
95 | 复制
96 |
97 | ```javascript
98 | 1void pthread_exit (void *status);
99 | ```
100 |
101 | pthread_exit用于终止线程,可以指定返回值,以便其他线程通过pthread_join函数获取该线程的返回值。
102 |
103 | 参数说明:
104 |
105 | void *status:指针线程终止的返回值。
106 |
107 | Linux内核只提供了轻量进程的支持,限制了更高效的线程模型的实现,但Linux着重优化了进程的调度开销,一定程度上弥补了这一缺陷。目前最为流行的线程机制LinuxThreads所采用的就是线程-进程“一对一”模型,调度交给核心,而在用户级实现一个包括信号处理在内的线程管理机制。
108 |
109 | **线程编程实例:pthread.c**
110 |
111 | 代码语言:javascript
112 |
113 | 复制
114 |
115 | ```javascript
116 | 1#include
117 | 2#include
118 | 3#include
119 | 4#include
120 | 5#include
121 | 6void *thread_1(void *arg)
122 | 7{
123 | 8 printf("thread one\n");
124 | 9}
125 | 10void *thread_2(void *arg)
126 | 11{
127 | 12 printf("thread two\n");
128 | 13}
129 | 14int main()
130 | 15{
131 | 16 int ret = 0;
132 | 17 pthread_t pid = 0;
133 | 18pthread_t pid1 = 0;
134 | 19 //创建线程1
135 | 20 ret = pthread_create(&pid, NULL, thread_1, NULL);
136 | 21 if(ret < 0)
137 | 22 {
138 | 23 perror("pthread_create");
139 | 24 exit(EXIT_FAILURE);
140 | 25 }
141 | 26 //创建线程2
142 | 27 ret = pthread_create(&pid1, NULL, thread_2, NULL);
143 | 28 if(ret < 0)
144 | 29 {
145 | 30 perror("pthread_create");
146 | 31 exit(EXIT_FAILURE);
147 | 32 }
148 | 33 //等待线程退出
149 | 34 pthread_join(pid, NULL);
150 | 35 pthread_join(pid1, NULL);
151 | 36 return 0;
152 | 37}
153 | ```
154 |
155 | 注意,在gcc中,默认是不包含线程相关的库的,所以在编译这个程序操作如下是会产生错误的,如图4-3-25所示。
156 |
157 | 
158 |
159 | 图4-3-25 gcc编译中没有包含线程库的验证结果
160 |
161 | 正确的编译方式是下面这样,要加上-lpthread这个库,确保编译的时候链接上。如图4-3-26所示。
162 |
163 | 
164 |
165 | 图4-3-26 创建线程
166 |
167 | 运行结果,如图4-3-27所示。
168 |
169 | 
170 |
171 | 图4-3-27 创建线程的实验结果
172 |
173 | pthread.c创建了2个线程,并在线程中实现打印功能,最终调用pthread_join等待子线程运行结束,一并退出。
174 |
175 | 通过上面的一个例程会发现一个问题,当我们去操作一个文件的时候会出现一个问题,就是不知道该听谁的,这时候我们就需要一个互斥锁,让线程一个个来,a执行完之后在执行b。
176 |
177 | **互斥锁例程:pthread2.c**
178 |
179 | 代码语言:javascript
180 |
181 | 复制
182 |
183 | ```javascript
184 | 1#include
185 | 2#include
186 | 3#include
187 | 4#include
188 | 5#include
189 | 6//定义一个互斥锁变量
190 | 7pthread_mutex_t m;
191 | 8void *thread_1(void *arg)
192 | 9{
193 | 10 //互斥锁加锁
194 | 11 pthread_mutex_lock(&m);
195 | 12 printf("thread one\n");
196 | 13 //互斥锁解锁
197 | 14 pthread_mutex_unlock(&m);
198 | 15}
199 | 16void *thread_2(void *arg)
200 | 17{
201 | 18 pthread_mutex_lock(&m);
202 | 19 printf("thread two\n");
203 | 20 pthread_mutex_unlock(&m);
204 | 21}
205 | 22int main()
206 | 23{
207 | 24 int ret = 0;
208 | 25 //以动态方式创建互斥锁
209 | 26 ret = pthread_mutex_init(&m, NULL);
210 | 27 if(ret < 0)
211 | 28 {
212 | 29 perror("pthread_mutex_init");
213 | 30 exit(EXIT_FAILURE);
214 | 31 }
215 | 32 pthread_t pid = 0;
216 | 33 pthread_t pid1 = 0;
217 | 34 ret = pthread_create(&pid, NULL, thread_1, NULL);
218 | 35 if(ret < 0)
219 | 36 {
220 | 37 perror("pthread_create");
221 | 38 exit(EXIT_FAILURE);
222 | 39 }
223 | 40 ret = pthread_create(&pid1, NULL, thread_2, NULL);
224 | 41 if(ret < 0)
225 | 42 {
226 | 43 perror("pthread_create");
227 | 44 exit(EXIT_FAILURE);
228 | 45 }
229 | 46 pthread_join(pid, NULL);
230 | 47 pthread_join(pid1, NULL);
231 | 48 return 0;
232 | 49}
233 | ```
234 |
235 | 一样的,同样执行编译加上-lpthread参数保证编译时链接线程库,然后运行,如图4-3-28所示。
236 |
237 | 
238 |
239 | 图4-3-28 添加互斥锁测试
240 |
241 | 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该函数的某个数据时,进行保护,其它线程不能进行访问直到该线程读取完成,其它线程才可以使用。不会出现数据不一致或者数据污染。
242 |
--------------------------------------------------------------------------------
/Linux01:概述及环境搭建.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/RT93qJdTagtKjWKx_A_6Nw
2 |
3 |
4 |
5 | # Linux01:概述及环境搭建
6 |
7 |
8 |
9 |
10 |
11 | ## 入门概述
12 |
13 | > 我们为什么要学习Linux
14 |
15 | linux诞生了这么多年,以前还喊着如何能取代windows系统,现在这个口号已经小多了,任何事物发展都有其局限性都有其天花板。就如同在国内再搞一个社交软件取代腾讯一样,想想而已基本不可能,因为用户已经习惯于使用微信交流,不是说技术上实现不了解而是老百姓已经习惯了,想让他们不用,即使他们自己不用亲戚朋友还是要用,没有办法的事情。
16 |
17 | 用习惯了windows操作系统,再让大家切换到别的操作系统基本上是不可能的事情,改变一个人已经养成的习惯太难。没有办法深入到普通老百姓的生活中,并不意味着linux就没有用武之地了。在服务器端,在开发领域linux倒是越来越受欢迎,很多程序员都觉得不懂点linux都觉得不好意思,linux在开源社区的地位依然岿然不动。
18 |
19 | 尤其是作为一个后端程序员,是必须要掌握Linux的,因为这都成为了你找工作的基础门槛了,所以不得不学习!
20 |
21 | > Linux 简介
22 |
23 | Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的。
24 |
25 | Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX(可移植操作系统接口) 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。
26 |
27 | Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议。它支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。
28 |
29 | > Linux 发行版
30 |
31 | Linux 的发行版说简单点就是将 Linux 内核与应用软件做一个打包。
32 |
33 | 
34 |
35 | 目前市面上较知名的发行版有:Ubuntu、RedHat、CentOS、Debian、Fedora、SuSE、OpenSUSE、Arch Linux、SolusOS 等。
36 |
37 | 
38 |
39 | > Linux 应用领域
40 |
41 | 今天各种场合都有使用各种 Linux 发行版,从嵌入式设备到超级计算机,并且在服务器领域确定了地位,通常服务器使用 LAMP(Linux + Apache + MySQL + PHP)或 LNMP(Linux + Nginx+ MySQL + PHP)组合。
42 |
43 | 目前 Linux 不仅在家庭与企业中使用,并且在政府中也很受欢迎。
44 |
45 | - 巴西联邦政府由于支持 Linux 而世界闻名。
46 | - 有新闻报道俄罗斯军队自己制造的 Linux 发布版的,做为 G.H.ost 项目已经取得成果。
47 | - 印度的 Kerala 联邦计划在向全联邦的高中推广使用 Linux。
48 | - 中华人民共和国为取得技术独立,在龙芯处理器中排他性地使用 Linux。
49 | - 在西班牙的一些地区开发了自己的 Linux 发布版,并且在政府与教育领域广泛使用,如 Extremadura 地区的 gnuLinEx 和 Andalusia 地区的 Guadalinex。
50 | - 葡萄牙同样使用自己的 Linux 发布版 Caixa Mágica,用于 Magalh?es 笔记本电脑和 e-escola 政府软件。
51 | - 法国和德国同样开始逐步采用 Linux。
52 |
53 |
54 |
55 | > Linux vs Windows
56 |
57 | 
58 |
59 |
60 |
61 | ## 环境搭建
62 |
63 | Linux 的安装,安装步骤比较繁琐,现在其实云服务器挺普遍的,价格也便宜,如果直接不想搭建,也可以直接买一台学习用用!
64 |
65 | > 安装CentOS(虚拟机安装,耗资源)
66 |
67 | 1、可以通过镜像进行安装!
68 |
69 | 2、可以使用我已经制作好的镜像!视频中讲解了该种方式!
70 |
71 | 3、安装 VMware 虚拟机软件,然后打开我们的镜像即可使用!
72 |
73 |
74 |
75 | > 购买云服务器(推荐)
76 |
77 | 虚拟机安装后占用空间,也会有些卡顿,我们作为程序员其实可以选择购买一台自己的服务器,这样的话更加接近真实线上工作;
78 |
79 | 1、阿里云购买服务器:https://www.aliyun.com/minisite/goods?userCode=0phtycgr
80 |
81 | 2、购买完毕后,获取服务器的ip地址,重置服务器密码,就可以远程登录了
82 |
83 | 3、下载 xShell 工具,进行远程连接使用!连接成功效果如下:
84 |
85 | 
86 |
87 | **注意事项:**
88 |
89 | 如果要打开端口,需要在阿里云的安全组面板中开启对应的出入规则,不然的话会被阿里拦截!
90 |
91 |
92 |
93 | > 如果前期不好操作,可以推荐安装宝塔面板,傻瓜式管理服务器
94 |
95 | 安装教程:https://www.bt.cn/bbs/thread-19376-1-1.html
96 |
97 | 1、开启对应的端口
98 |
99 | 2、一键安装
100 |
101 | 3、安装完毕后会得到远程面板的地址,账号,密码,就可以登录了
102 |
103 | 4、登录之后就可以可视化的安装环境和部署网站!
104 |
105 | 
106 |
107 | > 关于域名
108 |
109 | 如果自己的网站想要上线,就一定要购买一个域名然后进行备案;
110 |
111 | 
112 |
113 | 备案的话需要一些认证和时间,备完完毕后,就可以解析到自己的网站了,这个时候就可以使用域名来进行服务器的访问!
114 |
115 |
116 |
117 | ## 走近Linux系统
118 |
119 | > 开机登录
120 |
121 | 开机会启动许多程序。它们在Windows叫做"服务"(service),在Linux就叫做"守护进程"(daemon)。
122 |
123 | 开机成功后,它会显示一个文本登录界面,这个界面就是我们经常看到的登录界面,在这个登录界面中会提示用户输入用户名,而用户输入的用户将作为参数传给login程序来验证用户的身份,密码是不显示的,输完回车即可!
124 |
125 | 一般来说,用户的登录方式有三种:
126 |
127 | - 命令行登录
128 | - ssh登录
129 | - 图形界面登录
130 |
131 | 最高权限账户为 root,可以操作一切!
132 |
133 | > 关机
134 |
135 | 在linux领域内大多用在服务器上,很少遇到关机的操作。毕竟服务器上跑一个服务是永无止境的,除非特殊情况下,不得已才会关机。
136 |
137 | 关机指令为:shutdown ;
138 |
139 | ```
140 | sync # 将数据由内存同步到硬盘中。
141 |
142 | shutdown # 关机指令,你可以man shutdown 来看一下帮助文档。例如你可以运行如下命令关机:
143 |
144 | shutdown –h 10 # 这个命令告诉大家,计算机将在10分钟后关机
145 |
146 | shutdown –h now # 立马关机
147 |
148 | shutdown –h 20:25 # 系统会在今天20:25关机
149 |
150 | shutdown –h +10 # 十分钟后关机
151 |
152 | shutdown –r now # 系统立马重启
153 |
154 | shutdown –r +10 # 系统十分钟后重启
155 |
156 | reboot # 就是重启,等同于 shutdown –r now
157 |
158 | halt # 关闭系统,等同于shutdown –h now 和 poweroff
159 | ```
160 |
161 | 最后总结一下,不管是重启系统还是关闭系统,首先要运行 **sync** 命令,把内存中的数据写到磁盘中。
162 |
163 | > 系统目录结构
164 |
165 | 登录系统后,在当前命令窗口下输入命令:
166 |
167 | ```
168 | ls /
169 | ```
170 |
171 | 你会看到如下图所示:
172 |
173 | 
174 |
175 | 树状目录结构:(Linux的一切资源都挂载在这个 / 根节点下)
176 |
177 | 
178 |
179 | **以下是对这些目录的解释:**
180 |
181 | - **/bin**:bin是Binary的缩写, 这个目录存放着最经常使用的命令。
182 |
183 | - **/boot:** 这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。
184 |
185 | - **/dev :** dev是Device(设备)的缩写, 存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。
186 |
187 | - **/etc:** 这个目录用来存放所有的系统管理所需要的配置文件和子目录。
188 |
189 | - **/home**:用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。
190 |
191 | - **/lib**:这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。
192 |
193 | - **/lost+found**:这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。
194 |
195 | - **/media**:linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。
196 |
197 | - **/mnt**:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。
198 |
199 | - **/opt**:这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。
200 |
201 | - **/proc**:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
202 |
203 | - **/root**:该目录为系统管理员,也称作超级权限者的用户主目录。
204 |
205 | - **/sbin**:s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。
206 |
207 | - **/srv**:该目录存放一些服务启动之后需要提取的数据。
208 |
209 | - **/sys**:这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。
210 |
211 | - **/tmp**:这个目录是用来存放一些临时文件的。
212 |
213 | - **/usr**:这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。
214 |
215 | - **/usr/bin:** 系统用户使用的应用程序。
216 |
217 | - **/usr/sbin:** 超级用户使用的比较高级的管理程序和系统守护程序。
218 |
219 | - **/usr/src:** 内核源代码默认的放置目录。
220 |
221 | - **/var**:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
222 |
223 | - **/run**:是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。
224 |
225 |
226 |
227 |
--------------------------------------------------------------------------------
/shell编程:编程就是这么简单.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/cOPDTSPXAgRvoH1wU_nZCg
2 |
3 |
4 |
5 |
6 |
7 | # shell编程:编程就是这么简单
8 |
9 |
10 |
11 | #### Q:
12 |
13 | 什么是shell编程?
14 |
15 |
16 |
17 | #### A:
18 |
19 | shell编程就是通过语法将bash命令或外部命令整合起来,搭配正则表达式、管道命令与数据流定向等功能,来实现我们要完成的任务。最简单的shell script就是将多条命令写在一起,让用户可以一次性执行多条命令,同时每个命令及其输入参数得以在纯文本的shell脚本中保存。shell脚本运行较慢,使用CPU资源较多,是一个很好的项目管理工具,但一般不用于大数据处理(注:本文部分例子来自《鸟哥的Linux私房菜》)。
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 
28 |
29 | ## 01shell脚本基本编写规则
30 |
31 | shell脚本基本规则如下:
32 |
33 | ①命令的执行是由上而下,自左而右,空白行会被忽略;
34 |
35 | ②空格不可省略,多个空格会被忽略;
36 |
37 | ③每读到一个[Enter]命令就开始执行,拓展下一行可以使用\[Enter];
38 |
39 | ④命令的执行需要加绝对路径,否则默认在当前路径寻找脚本命令;
40 |
41 | ⑤通过环境变量PATH可设置脚本命令的查询范围,来简化脚本。
42 |
43 | 一个简单的shell脚本helloword如下所示:
44 |
45 | ```
46 | #!/bin/bash#Show "Hello World!" in the screen#20170320 tengwkPATH=/opt/node/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbinexport PATHecho -e "Hello World! \n"exit 1
47 | ```
48 |
49 | 脚本一般分为四部分。其中第一行#!/bin/bash声明脚本类型(更为普遍来说是语言解释器的路径),为bash脚本,除此之外其余#后面均为注释内容;之后为脚本环境变量例如PATH和LANG设置,对于命令的执行非常重要;第三部分为主要程序执行部分,上面程序的含义是在屏幕上显示“Hello World!”,-e表示使反斜杠转义,“\n”表示换行并插入新一行;第四部分为告知执行结果,利用exit可以自定义错误信息,可以使用环境变量?查看。脚本运行如下所示:
50 |
51 | 
52 |
53 | ## 02shell脚本基本结构
54 |
55 | shell脚本的两个基本结构就是判断结构和循环结构,判断结构使用方法如下所示:
56 |
57 | ```
58 | if [ 判断条件 ]; then执行命令1elif [ 判断条件 ]; then执行命令2fi
59 | ```
60 |
61 | 不同判断条件之间可以通过逻辑连接符连接,接下来我们通过一个askfor help小脚本来练习:
62 |
63 | ```
64 | #!/bin/bash#ask if you can help me# 20170330 tengwkPATH=/opt/node/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbinexport PATHread -p "Can you help me (Y/N): " answerif [ "$answer" == "Y" ] || [ "$answer" == "y" ]; then#其中 [ "$answer" == "Y" ] || [ "$answer" == "y" ]也可以改写为[ "$answer" == "Y" -o "$answer" == "y" ]echo "I'm so glad to hear that, thank you!"elif [ "$answer" == "N" ] || [ "$answer" == "n" ]; thenecho "Thank you all the same!"elseecho "Sorry, i can't understand you!"exit 1fi
65 | ```
66 |
67 | 运行示例如下:
68 |
69 | 
70 |
71 | if可以使用的判断符号有:
72 |
73 | ①字符串判断
74 |
75 | str1== str2 当两个串有相同内容、长度时为真
76 |
77 | str1!= str2 当串str1和str2不等时为真
78 |
79 | -nstr1 当串的长度大于0时为真(串非空)
80 |
81 | -zstr1 当串的长度为0时为真(空串)
82 |
83 | str1 当串str1为非空时为真
84 |
85 | ②数字的判断
86 |
87 | int1-eq int2 两数相等为真
88 |
89 | int1-ne int2 两数不等为真
90 |
91 | int1-gt int2 int1大于int2为真
92 |
93 | int1-ge int2 int1大于等于int2为真
94 |
95 | int1-lt int2 int1小于int2为真
96 |
97 | int1-le int2 int1小于等于int2为真
98 |
99 | ③文件的判断
100 |
101 | -rfile 用户可读为真
102 |
103 | -wfile 用户可写为真
104 |
105 | -xfile 用户可执行为真
106 |
107 | -ffile 文件为正规文件为真
108 |
109 | -dfile 文件为目录为真
110 |
111 | -cfile 文件为字符特殊文件为真
112 |
113 | -bfile 文件为块特殊文件为真
114 |
115 | -sfile 文件大小非0时为真
116 |
117 | -tfile 当文件描述符(默认为1)指定的设备为终端时为真
118 |
119 | ④复杂逻辑判断
120 |
121 | -a 与
122 |
123 | -o 或
124 |
125 | ! 非
126 |
127 | while循环结构使用方法如下:
128 |
129 | ```
130 | while [ 条件 ] do执行命令done
131 | ```
132 |
133 | 或者更为简单的可以在命令行执行的:
134 |
135 | ```
136 | while 条件; do 执行命令; done
137 | ```
138 |
139 | 下面是一个选择食物的selectfood脚本:
140 |
141 | ```
142 | #!/bin/bash#to input foods you like# 20170330 tengwkPATH=/opt/node/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbinexport PATHwhile [ "$word" != "END" -a "$word" != "end" ]#或者 until [ "$word" == "END" -o "$word" == "end" ]doread -p "Please input the foods you like, and press END to stop: " worddoneecho "OK! Now i know what you want eat."
143 | ```
144 |
145 | 运行示例如下:
146 |
147 | 
148 |
149 | 另一个更为常用的循环结构是for循环,常用来批量执行任务,如下所示:
150 |
151 | ```
152 | for 变量名 in 单词组do 执行命令done
153 | ```
154 |
155 | 其中单词组不同单词之间空格或者换行符分隔,例如我们进入不同项目文件夹批量解压序列文件:
156 |
157 | ```
158 | for id in `ls`do cd $id gzip -d raw_reads.fq.gz cd ..done
159 | ```
160 |
161 | ## 03shell脚本命令行参数
162 |
163 | 命令行参数是程序与用户交互的重要过程,能大大提高程序脚本的适用性。前面的read命令就是一个用户与程序交互的过程。在shell脚本中,命令行参数可以直接加在脚本后面,在脚本里使用默认变量“$n”来调用(n为非负整数),下面通过一个小例子来了解shell脚本命令行参数使用方法:
164 |
165 | ```
166 | echo $0echo $1echo $2
167 | ```
168 |
169 | 将上面脚本保存为sh04.sh并运行:
170 |
171 | 
172 |
173 | 可以看出第一个变量$0为脚本名字,从$1开始为用户输入数据。当n大于10时需要添加大括号,例如${10}。
174 |
175 | 在if结构里添加参数-n可以检查命令行参数是否存在,$#可以表示参数个数,$@用来提取所有参数并构成数组,$*用来提取所有参数并构成字符串,如下所示:
176 |
177 | ```
178 | if [ -n “$1” ]; then echo "Arguments exist!"else echo "No arguments"fiif [ $# -ne 2 ]; then echo "There are $#arguments"fiecho $@
179 | ```
180 |
181 | 将上面脚本保存为sh05.sh,运行如下所示:
182 |
183 | 
184 |
185 | 假如想设置命令行选项,可以使用getopts函数,该函数可以将命令行内容转换为变量。getopts包含两个内置变量,OPTARG和OPTIND。OPTARG就是将选项后面的参数保存在这个变量当中;OPTIND:这个表示命令行的下一个选项或参数的位置。
186 |
187 | 语法格式:getopts[option[:]] VARIABLE
188 |
189 | getopts有两个参数,第一个参数是一个字符串,包括字符和“:”,每一个字符都是一个有效的选项,如果字符后面带有“:”,表示这个字符有自己的参数。getopts从命令中获取这些参数,并且删去了“-”,并将其赋值在第二个参数中,如果带有自己参数,这个参数赋值在“OPTARG”中。
190 |
191 | 具体实例如下所示:
192 |
193 | ```
194 | echo $*while getopts ":a:bc" optdo case $opt in a ) echo $OPTARG echo $OPTIND;; b ) echo "b $OPTIND";; c ) echo "c $OPTIND";; ? ) echo "error" exit 1;; esacdoneecho $OPTINDshift $(($OPTIND - 1))#通过shift $(($OPTIND - 1))的处理,$*中就只保留了除去选项内容的参数,可以继续使用后面的位置参数。echo $0echo $*
195 | ```
196 |
197 | 其中":a:bc",这就是一个选项字符串。对应到命令行就是-a ,-b ,-c。冒号又是什么呢?第一个冒号表示忽略错误,选项后面的冒号表示参数,一个冒号就表示这个选项后面必须带有参数,但是这个参数可以和选项连在一起写,也可以用空格隔开,比如-a123 和-a 123(中间有空格)都表示123是-a的参数;两个冒号的就表示这个选项的参数是可选的,即可以有参数,也可以没有参数,但要注意有参数时,参数与选项之间不能有空格。将上面脚本保存为getopts.sh。并运行如下所示:
198 |
199 | 
200 |
201 | 
202 |
203 |
--------------------------------------------------------------------------------
/73条日常Linux shell命令汇总.md:
--------------------------------------------------------------------------------
1 | # 73条日常Linux shell命令汇总,总有一条你需要!
2 |
3 |
4 |
5 | > 英文:TechBar
6 | >
7 | > 译文:外刊IT评论
8 | >
9 | > 链接:http://www.vaikan.com/linux-shell-tips-and-tricks/
10 |
11 |
12 |
13 | > **1检查远程端口是否对bash开放:**
14 |
15 | ```
16 | echo >/dev/tcp/8.8.8.8/53 && echo "open"
17 | ```
18 |
19 | > **2让进程转入后台:**
20 |
21 | ```
22 | Ctrl + z
23 | ```
24 |
25 | > **3.将进程转到前台:**
26 |
27 | ```
28 | fg
29 | ```
30 |
31 | > **4.产生随机的十六进制数,其中n是字符数:**
32 |
33 | ```
34 | openssl rand -hex n
35 | ```
36 |
37 | > **5.在当前shell里执行一个文件里的命令:**
38 |
39 | ```
40 | source /home/user/file.name
41 | ```
42 |
43 | > **6.截取前5个字符:**
44 |
45 | ```
46 | ${variable:0:5}
47 | ```
48 |
49 | > **7.SSH debug 模式:**
50 |
51 | ```
52 | ssh -vvv user@ip_address
53 | ```
54 |
55 | > **8.SSH with pem key:**
56 |
57 | ```
58 | ssh user@ip_address -i key.pem
59 | ```
60 |
61 | > **9.用wget抓取完整的网站目录结构,存放到本地目录中:**
62 |
63 | ```
64 | wget -r --no-parent --reject "index.html*" http://hostname/ -P /home/user/dirs
65 | ```
66 |
67 | > **10.一次创建多个目录:**
68 |
69 | ```
70 | mkdir -p /home/user/{test,test1,test2}
71 | ```
72 |
73 | > **11.列出包括子进程的进程树:**
74 |
75 | ```
76 | ps axwef
77 | ```
78 |
79 | > **12.创建 war 文件:**
80 |
81 | ```
82 | jar -cvf name.war file
83 | ```
84 |
85 | > **13.测试硬盘写入速度:**
86 |
87 | ```
88 | dd if=/dev/zero of=/tmp/output.img bs=8k count=256k; rm -rf /tmp/output.img
89 | ```
90 |
91 | > **14.测试硬盘读取速度:**
92 |
93 | ```
94 | hdparm -Tt /dev/sda
95 | ```
96 |
97 | > **15.获取文本的md5 hash:**
98 |
99 | ```
100 | echo -n "text" | md5sum
101 | ```
102 |
103 | > **16.检查xml格式:**
104 |
105 | ```
106 | xmllint --noout file.xml
107 | ```
108 |
109 | > **17.将tar.gz提取到新目录里:**
110 |
111 | ```
112 | tar zxvf package.tar.gz -C new_dir
113 | ```
114 |
115 | > **18.使用curl获取HTTP头信息:**
116 |
117 | ```
118 | curl -I http://www.example.com
119 | ```
120 |
121 | > **19.修改文件或目录的时间戳(YYMMDDhhmm):**
122 |
123 | ```
124 | touch -t 0712250000 file
125 | ```
126 |
127 | > **20.用wget命令执行ftp下载:**
128 |
129 | ```
130 | wget -m ftp://username:password@hostname
131 | ```
132 |
133 | > **21.生成随机密码(例子里是16个字符长):**
134 |
135 | ```
136 | LANG=c < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16};echo;
137 | ```
138 |
139 | > **22.快速备份一个文件:**
140 |
141 | ```
142 | cp some_file_name{,.bkp}
143 | ```
144 |
145 | > **23.访问Windows共享目录:**
146 |
147 | ```
148 | smbclient -U "DOMAIN\user" //dc.domain.com/share/test/dir
149 | ```
150 |
151 | > **24.执行历史记录里的命令(这里是第100行):**
152 |
153 | ```
154 | !100
155 | ```
156 |
157 | > **25.解压:**
158 |
159 | ```
160 | unzip package_name.zip -d dir_name
161 | ```
162 |
163 | > **26.输入多行文字(CTRL + d 退出):**
164 |
165 | ```
166 | cat > test.txt
167 | ```
168 |
169 | > **27.创建空文件或清空一个现有文件:**
170 |
171 | ```
172 | \> test.txt
173 | ```
174 |
175 | > **28.与Ubuntu NTP server同步时间:**
176 |
177 | ```
178 | ntpdate ntp.ubuntu.com
179 | ```
180 |
181 | > **29.用netstat显示所有tcp4监听端口:**
182 |
183 | ```
184 | netstat -lnt4 | awk '{print $4}' | cut -f2 -d: | grep -o '[0-9]*'
185 | ```
186 |
187 | > **30.qcow2镜像文件转换:**
188 |
189 | ```
190 | qemu-img convert -f qcow2 -O raw precise-server-cloudimg-amd64-disk1.img \precise-server-cloudimg-amd64-disk1.raw
191 | ```
192 |
193 | > **31.重复运行文件,显示其输出(缺省是2秒一次):**
194 |
195 | ```
196 | watch ps -ef
197 | ```
198 |
199 | > **32.所有用户列表:**
200 |
201 | ```
202 | getent passwd
203 | ```
204 |
205 | > **33.Mount root in read/write mode:**
206 |
207 | ```
208 | mount -o remount,rw /
209 | ```
210 |
211 | > **34.挂载一个目录(这是不能使用链接的情况):**
212 |
213 | ```
214 | mount --bind /source /destination
215 | ```
216 |
217 | > **35.动态更新DNS server:**
218 |
219 | ```
220 | nsupdate < **36.递归grep所有目录:**
227 |
228 | ```
229 | grep -r "some_text" /path/to/dir
230 | ```
231 |
232 | > **37.列出前10个最大的文件:**
233 |
234 | ```
235 | lsof / | awk '{ if($7 > 1048576) print $7/1048576 "MB "$9 }' | sort -n -u | tail
236 | ```
237 |
238 | > **38.显示剩余内存(MB):**
239 |
240 | ```
241 | free -m | grep cache | awk '/[0-9]/{ print $4" MB" }'
242 | ```
243 |
244 | > **39.打开Vim并跳到文件末:**
245 |
246 | ```
247 | vim + some_file_name
248 | ```
249 |
250 | > **40.Git 克隆指定分支(master):**
251 |
252 | ```
253 | git clone git@github.com:name/app.git -b master
254 | ```
255 |
256 | > **41.Git 切换到其它分支(develop):**
257 |
258 | ```
259 | git checkout develop
260 | ```
261 |
262 | > **42.Git 删除分支(myfeature):**
263 |
264 | ```
265 | git branch -d myfeature
266 | ```
267 |
268 | > **43.Git 删除远程分支**
269 |
270 | ```
271 | git push origin :branchName
272 | ```
273 |
274 | > **44.Git 将新分支推送到远程服务器:**
275 |
276 | ```
277 | git push -u origin mynewfeature
278 | ```
279 |
280 | > **45.打印历史记录中最后一次cat命令:**
281 |
282 | ```
283 | !cat:p
284 | ```
285 |
286 | > **46.运行历史记录里最后一次cat命令:**
287 |
288 | ```
289 | !cat
290 | ```
291 |
292 | > **47.找出/home/user下所有空子目录:**
293 |
294 | ```
295 | find /home/user -maxdepth 1 -type d -empty
296 | ```
297 |
298 | > **48.获取test.txt文件中第50-60行内容:**
299 |
300 | ```
301 | < test.txt sed -n '50,60p'
302 | ```
303 |
304 | > **49.运行最后一个命令(如果最后一个命令是mkdir /root/test, 下面将会运行: sudo mkdir /root/test):**
305 |
306 | ```
307 | sudo !!
308 | ```
309 |
310 | > **50.创建临时RAM文件系统 – ramdisk (先创建/tmpram目录):**
311 |
312 | ```
313 | mount -t tmpfs tmpfs /tmpram -o size=512m
314 | ```
315 |
316 | > **51.Grep whole words:**
317 |
318 | ```
319 | grep -w "name" test.txt
320 | ```
321 |
322 | > **52.在需要提升权限的情况下往一个文件里追加文本:**
323 |
324 | ```
325 | echo "some text" | sudo tee -a /path/file
326 | ```
327 |
328 | > **53.列出所有kill signal参数:**
329 |
330 | ```
331 | kill -l
332 | ```
333 |
334 | > **54.在bash历史记录里禁止记录最后一次会话:**
335 |
336 | ```
337 | kill -9 $$
338 | ```
339 |
340 | > **55.扫描网络寻找开放的端口:**
341 |
342 | ```
343 | nmap -p 8081 172.20.0.0/16
344 | ```
345 |
346 | > **56.设置git email:**
347 |
348 | ```
349 | git config --global user.email "me@example.com"
350 | ```
351 |
352 | > **57.To sync with master if you have unpublished commits:**
353 |
354 | ```
355 | git pull --rebase origin master
356 | ```
357 |
358 | > **58.将所有文件名中含有”txt”的文件移入/home/user目录:**
359 |
360 | ```
361 | find -iname "*txt*" -exec mv -v {} /home/user \;
362 | ```
363 |
364 | > **59.将文件按行并列显示:**
365 |
366 | ```
367 | paste test.txt test1.txt
368 | ```
369 |
370 | > **60.shell里的进度条:**
371 |
372 | ```
373 | pv data.log
374 | ```
375 |
376 | > **61.使用netcat将数据发送到Graphite server:**
377 |
378 | ```
379 | echo "hosts.sampleHost 10 `date +%s`" | nc 192.168.200.2 3000
380 | ```
381 |
382 | > **62.将tabs转换成空格:**
383 |
384 | ```
385 | expand test.txt > test1.txt
386 | ```
387 |
388 | > **63.Skip bash history:**
389 |
390 | ```
391 | < space >cmd
392 | ```
393 |
394 | > **64.去之前的工作目录:**
395 |
396 | ```
397 | cd -
398 | ```
399 |
400 | > **65.拆分大体积的tar.gz文件(每个100MB),然后合并回去:**
401 |
402 | ```
403 | split –b 100m /path/to/large/archive /path/to/output/files
404 | cat files* > archive
405 | ```
406 |
407 | > **66.使用curl获取HTTP status code:**
408 |
409 | ```
410 | curl -sL -w "%{http_code}\\n" www.example.com -o /dev/null
411 | ```
412 |
413 | > **67.设置root密码,强化MySQL安全安装:**
414 |
415 | ```
416 | /usr/bin/mysql_secure_installation
417 | ```
418 |
419 | > **68.当Ctrl + c不好使时:**
420 |
421 | ```
422 | Ctrl + \
423 | ```
424 |
425 | > **69.获取文件owner:**
426 |
427 | ```
428 | stat -c %U file.txt
429 | ```
430 |
431 | > **70.block设备列表:**
432 |
433 | ```
434 | lsblk -f
435 | ```
436 |
437 | > **71.找出文件名结尾有空格的文件:**
438 |
439 | ```
440 | find . -type f -exec egrep -l " +$" {} \;
441 | ```
442 |
443 | > **72.找出文件名有tab缩进符的文件**
444 |
445 | ```
446 | find . -type f -exec egrep -l $'\t' {} \;
447 | ```
448 |
449 | > **73.用”=”打印出横线:全选复制放进笔记**
450 |
451 | ```
452 | printf '%100s\n' | tr ' ' =
453 | ```
454 |
455 |
456 |
457 |
--------------------------------------------------------------------------------
/Linux系统安装详细教程.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/kTHAS_DpRxInODju_JOdVw
2 |
3 |
4 |
5 | # Linux系统安装详细教程
6 |
7 |
8 |
9 | ## **下载Vmware**
10 |
11 | 去官网直接下载
12 |
13 | 
14 |
15 |
16 |
17 | **安装激活Vmware**
18 |
19 |
20 |
21 | VMware Workstation Pro 15永久许可证激活密钥(任选其一)
22 |
23 |
24 |
25 | YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8
26 | UG5J2-0ME12-M89WY-NPWXX-WQH88
27 | UA5DR-2ZD4H-089FY-6YQ5T-YPRX6
28 | GA590-86Y05-4806Y-X4PEE-ZV8E0
29 | ZF582-0NW5N-H8D2P-0XZEE-Z22VA
30 | YA18K-0WY8P-H85DY-L4NZG-X7RADD
31 |
32 |
33 |
34 | VMware 15官方完整版,安装后采用上面的VMware许可证密钥激活即可,功能完整无缺,适合追求完美的用户使用。
35 |
36 | 
37 |
38 |
39 |
40 |
41 |
42 | ## **下载Liunx(推荐使用Ubuntu18.04.5)**
43 |
44 | 去官网直接下载
45 |
46 | 
47 |
48 |
49 |
50 | 
51 |
52 |
53 |
54 |
55 |
56 | ## 开始创建
57 |
58 |
59 |
60 | 首先打开第一步下载好的WMwaer
61 |
62 | 点击创建新的虚拟机
63 |
64 | 
65 |
66 |
67 |
68 |
69 |
70 | 点击推荐的“典型”配置
71 |
72 | 
73 |
74 |
75 |
76 |
77 |
78 | 稍后安装操作系统
79 |
80 | 
81 |
82 |
83 |
84 | 选择Linux
85 |
86 | 
87 |
88 |
89 |
90 | 然后就是起一个用户名字,选择要安装的位置
91 |
92 |
93 |
94 | 虚拟机处理器数量及内核都选择2,对于开发来说够用了。即使不够用的话,这个参数也是可以修改的。
95 |
96 | 
97 |
98 |
99 |
100 |
101 |
102 | 内存选择2048M,也就是2G,最好选择1G,2G,4G,8G,不要选择3G这样的。
103 |
104 | 
105 |
106 |
107 |
108 |
109 |
110 | 后面这几步都可以直接“下一步”即可
111 |
112 | 
113 |
114 |
115 |
116 |
117 |
118 | 虚拟机所产生的文件特别大,所以选择位置所在的磁盘最好剩余空间大一些。建议设置为20,如果磁盘空间不够可以选择40,这个空间不是实时占用。
119 |
120 | 
121 |
122 |
123 |
124 |
125 |
126 | 点击自定义硬件
127 |
128 | 
129 |
130 |
131 |
132 |
133 |
134 | 点击CD/DVD,右侧选择使用ISO映像文件,选择你第二步下载好的Linux系统文件
135 |
136 | 
137 |
138 |
139 |
140 |
141 |
142 | 创建完成后开机
143 |
144 |
145 |
146 | 建议使用English英语
147 |
148 | 
149 |
150 |
151 |
152 |
153 |
154 | 这一步直接选择默认
155 |
156 | 
157 |
158 |
159 |
160 |
161 |
162 | 这里也是选择默认,然后点击 “Install Now”,之后的弹出窗口里点击 “continue”
163 |
164 | 
165 |
166 | -
167 |
168 | - 在Where Are You?里面,地图里点击中国,然后点击 “continue”
169 |
170 | - 
171 |
172 |
173 |
174 | 填写好个人信息,接下来就进入了下载安装的过程,整个过程大概需要20分钟。
175 |
176 | 
177 |
178 |
179 |
180 | 安装完毕之后选择 “restart now”,重启虚拟机。至此,虚拟机及Linux系统均已经安装完成。
181 |
182 |
183 |
184 | 
185 |
186 |
187 |
188 | Ubuntu刚安装完毕之后,还无法进行开发,因为有些环境还未设置好,比如:升级vi到vim,源的更换,等等。
189 |
190 |
191 |
192 | 在对Ubuntu进行配置时,命令行窗口(Shell)是必须的,但Ubuntu默认未将这个命令行窗口放在左边任务栏里,因此我们要先把它调出来。
193 |
194 |
195 |
196 | 调出来的方法也很简单,首先点击任务栏下方的九个点的那个图标,然后往下滚一屏,就可以找到termical(终端)那个图标的。或者在上方的搜索栏里直接输入 “terminal”也可以找到它。
197 |
198 | 
199 |
200 |
201 |
202 | 因为我们对命令行窗口非常常用,所以我们可以将它固定在任务栏里。在Ubuntu 18.04里,只需将终端的图标从任务栏下面拖拽到上面即可自动固定在任务栏里,其它版本的Ubuntu可能需要右击,然后选择 “Add to Favorites”
203 |
204 | 
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | **安装VMware tools**
213 |
214 |
215 |
216 | VMware tools可以更方便的管理虚拟机,比如共享剪贴板,也就是在虚拟机里复制文字可以直接粘贴到Window主机里,反之亦可。
217 |
218 | ###
219 |
220 | ### 安装过程:
221 |
222 | - 点击“虚拟机” 然后 “安装VMwareTools(T)”,如有弹出窗口“CD-ROM门锁定”,则点击“是”
223 |
224 | - 
225 |
226 |
227 |
228 | 打开命令行窗口,输入代码将安装包拷备至当前目录
229 |
230 |
231 |
232 | 输入cp /media/liangxu/VMware\ Tools/VMwareTools-10.2.0-7259539.tar.gz .
233 |
234 | 回车
235 |
236 |
237 |
238 | 此处的“liangxu”应替换为你的用户名,具体可以在桌面点击“文件图标”,将鼠标放在左边目录的倒数第二个即可显现路径,同理,“VMwareTools-10.2.0-7259539.tar.gz”也要替换为你下载的安装包名,这里是以我的文件名举例子。
239 |
240 |
241 |
242 | 将“VMwareTools-10.2.0-7259539.tar.gz”替换为你下载的安装包名
243 |
244 |
245 |
246 | 输入tar zxf VMwareTools-10.2.0-7259539.tar.gz
247 |
248 | 回车
249 |
250 |
251 |
252 | 进到vmware-tools-distrib,安装VMware tools。安装过程第一次询问的时候,输入 “yes” ,之后一路回车即可。
253 |
254 |
255 |
256 | 输入cd VMware-tools-distrib/
257 |
258 | 回车
259 |
260 |
261 |
262 | 最后输入sudo ./VMware-install.pl
263 |
264 | 回车
265 |
266 | 
267 |
268 |
269 |
270 | 安装完毕之后,将安装包删除即可。其实如果把安装包拷备到/tmp目录下的话,这一步不用做。
271 |
272 |
273 |
274 | VMware Tools安装完毕之后,需要重启虚拟机,相应的功能才会启用,比如:共享剪贴板。
275 |
276 | ## 更改软件源
277 |
278 | 打来soft文件
279 |
280 | 
281 |
282 |
283 |
284 | 选择Download from后面的网址
285 |
286 | 
287 |
288 | 更换为阿里云的“mirrors.aliyun.com”
289 |
290 | 这样服务器就设置成国内服务器了,当然也可以更改成其他国内服务器。
291 |
292 | 
293 |
294 | 这样Linux就能正常使用了。
295 |
296 |
297 |
298 |
--------------------------------------------------------------------------------
/Linux环境都没有,怎么学编程?.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/WeZLtfrMdnISpX3v5WpJfA
2 |
3 |
4 |
5 | # Linux环境都没有,怎么学编程?
6 |
7 |
8 |
9 |
10 |
11 | ------
12 |
13 | # 憋说了,整一套吧!
14 |
15 | 本文准备从0开始,一步步搭建一套属于自己的**多节点Linux系统环境**,这将是后续**学Linux**、**用Linux**、**Linux环境编程**、**应用和项目部署**、**工具实验**等一系列学习和实践的基石,希望对小伙伴们有帮助。
16 |
17 | 提前备好Linux编程实验环境非常重要,建议人手一套,这样以后每当学完一个理论知识需要实践时,立马就可以拿到上面去练手了。
18 |
19 | 因此本文先把环境给搭建起来!
20 |
21 | ------
22 |
23 | # 软件准备
24 |
25 | - `VMware`虚拟机软件:本文使用的是`VMware Fusion 10.1.0`版本
26 | - `CentOS`操作系统`ISO`镜像:`CentOS 7.4 64位`
27 | - SSH终端软件:`SecureCRT`
28 | - SFTP文件传输工具:`Transmit`
29 | - 物理宿主机系统:`macOS Catalina 10.15.4`
30 |
31 | ------
32 |
33 | # 安装Linux操作系统
34 |
35 | **1、创建新的虚拟机**
36 |
37 | 
38 |
39 | **2、选择固件类型**
40 |
41 | 
42 |
43 | 默认即可
44 |
45 | **3、选择自定义设置**
46 |
47 | 
48 |
49 | **4、进入自定义设置**
50 |
51 | 我们初步需要自定义的主要也就是**处理器**、**内存**、**硬盘**,可以根据宿主机性能按需分配。
52 |
53 | 
54 |
55 | 
56 |
57 | 
58 |
59 | **5、启动虚拟机**
60 |
61 | 
62 |
63 | 如果有权限提示,记得打开权限允许,否则可能会报错
64 |
65 | 
66 |
67 | 正式点击启动键,过程中各种提示权限的允许动作,建议都通过一下。
68 |
69 | **6、进入系统安装界面**
70 |
71 | 
72 |
73 | 
74 |
75 | **7、选择安装语言**
76 |
77 | 
78 |
79 | **8、选择预安装的软件**
80 |
81 | 
82 |
83 | 
84 |
85 | **9、配置分区**
86 |
87 | 
88 |
89 | 
90 |
91 | 没有特别需求可以选择自动分区,大家如果有需要可以自定义分区。
92 |
93 | **10、进入正式安装过程**
94 |
95 | 
96 |
97 | 
98 |
99 | **11、安装完成并重启**
100 |
101 | 
102 |
103 | **12、进入新系统**
104 |
105 | 
106 |
107 | 
108 |
109 | ------
110 |
111 | # 系统是装好了,但还有几个问题
112 |
113 | **问题一:** 虚拟机内Linux系统与外网无法连通
114 |
115 | 
116 |
117 | **问题二:** 虚拟机内Linux系统与外部宿主机无法连通
118 |
119 | 比如我这里的物理宿主机的IP地址为:`192.168.31.35`
120 |
121 | 
122 |
123 | **问题三:** 虚拟机内Linux系统节点与节点之间无法连通(如果装了多个Linux节点的话)
124 |
125 | ------
126 |
127 | # 网络配置(极其重要!)
128 |
129 | **1、首先尝试查看虚拟机系统的IP地址**
130 |
131 | 使用命令`ifconfig`进行查看。我们会发现装好的系统并没有为它设置IP地址。
132 |
133 | **2、设置虚拟机与物理宿主机的网络连接**
134 |
135 | 
136 |
137 | 首先选择**桥接模式**,另外由于我的物理主机是通过WiFi的方式连接到路由器最终访问外网,所以此处我选择的是`Wi-Fi`这一项
138 |
139 | 
140 |
141 | 小伙伴们可以按实际情况进行选择。
142 |
143 | **3、为虚拟机配置固定静态IP**
144 |
145 | 首先使用`dhclient`工具为本机分配一个网络内可用的IP地址:
146 |
147 | 
148 |
149 | 接下来编辑虚拟机系统网卡配置,将上面分配所得的IP地址配置进去:
150 |
151 | 使用命令编辑:`vim /etc/sysconfig/network-scripts/ifcfg-ens33`
152 |
153 | 修改配置如下:
154 |
155 | ```
156 | TYPE=Ethernet
157 | PROXY_METHOD=none
158 | BROWSER_ONLY=no
159 | BOOTPROTO=static
160 | DEFROUTE=yes
161 | IPV4_FAILURE_FATAL=no
162 | IPV6INIT=yes
163 | IPV6_AUTOCONF=yes
164 | IPV6_DEFROUTE=yes
165 | IPV6_FAILURE_FATAL=no
166 | IPV6_ADDR_GEN_MODE=stable-privacy
167 | NAME=ens33
168 | UUID=824ec4bd-a9ae-4410-8346-17ce7f3dd111
169 | DEVICE=ens33
170 | ONBOOT=yes
171 | IPADDR=192.168.31.110
172 | NETMASK=255.255.255.0
173 | GATEWAY=192.168.31.1
174 | DNS1=119.29.29.29
175 | ```
176 |
177 | 尤其注意下图红色标记部分的配置:
178 |
179 | 
180 |
181 | 编辑完成,重启网络设置即可
182 |
183 | ```
184 | systemctl restart network.service
185 | ```
186 |
187 | ------
188 |
189 | ## **检查安装配置结果**
190 |
191 | **1、首先检查IP配置结果**
192 |
193 | 
194 |
195 | **2、检验虚拟机系统网络和外界的连通性**
196 |
197 | 包括检查和外网的连通、和物理宿主机的连通、以及和兄弟节点(前提是你安装了多个虚拟机系统节点的话)之间的连接
198 |
199 | 
200 |
201 | 3、反向检查物理宿主机和虚拟机系统网络的连接性
202 |
203 | 
204 |
205 | 至此,大功告成!
206 |
207 | ------
208 |
209 | # SSH远程连接
210 |
211 | 在宿主机通过SSH终端连接虚拟机内Linux系统,成功!
212 |
213 | 
214 |
215 | ------
216 |
217 | # SFTP文件传输
218 |
219 | 在宿主机通过SFTP工具即可访问虚拟机内Linux节点,从而可以实现本地和服务器的文件互传
220 |
221 | 
222 |
223 | 这样一来,一个可用的Linux节点就打造完成了!
224 |
225 | ------
226 |
227 | # 何不再多弄几个节点?
228 |
229 | 可以完全重复以上步骤再打造出多个Linux节点,当然**更简单的方式**则是直接通过上面已经装好了的虚拟机节点**直接克隆**,来快速生成其他节点。
230 |
231 | 
232 |
233 | 
234 |
235 | 克隆完成之后,只需要再配置一下新节点的网络即可。
236 |
237 | ------
238 |
239 | # 后记
240 |
241 | 好啦,现在**多节点的Linux环境**终于搭建完成了,后续不管是 **学Linux**、**用Linux**,还是**Linux环境编程**、**应用和项目部署**、**工具实验**,都有可以动手实践的地方了。
242 |
243 | ------
244 |
245 |
--------------------------------------------------------------------------------
/Android NDK POSIX 多线程编程.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://cloud.tencent.com/developer/article/1832838
2 |
3 |
4 |
5 | # Android NDK POSIX 多线程编程
6 |
7 |
8 |
9 | 本篇详细介绍一下 POSIX 多线程编程常用的 API 。
10 |
11 | **1. POSIX**
12 |
13 | POSIX 全称是 Portable Operating System Interface of UNIX ,表示可移植操作系统接口,本质上是一种编程标准。它定义了操作系统应该为应用程序提供的接口标准,是 IEEE 为要在各种 UNIX 操作系统上运行的软件而定义的一系列 API 标准的总称。
14 |
15 | **2. Pthreads**
16 |
17 | POSIX 线程是 POSIX 的线程标准,也称为 Pthreads ,它定义了创建和管理线程的一套 API 。本文的 Pthreads 是实现 POSIX 线程标准的 c 语言编程库。在 Linux 系统中,一般多线程的实现由 POSIX 多线程编程实现,而 Android 系统基于 Linux 系统,原生便支持 POSIX 多线程编程。
18 |
19 | POSIX Linux 编译命令:gcc hello.c -o hello -lpthread,执行命令:./hello 。
20 |
21 | 由于本文讲的是 NDK 开发,代码编译基于 Android 平台实现。
22 |
23 | **3. POSIX 线程创建**
24 |
25 | 线程创建相关 API:
26 |
27 | \1. pthread_t 线程 id 。
28 |
29 | \2. pthread_create 负责创建线程,传入 pthread_t 的指针,线程的 执行方法和传入线程的参数。
30 |
31 | \3. pthread_join 使当前线程挂起,等待指定线程执行结束,并获取 线程返回值。
32 |
33 | \4. pthread_exit 退出当前线程,并且可以设置当前线程的返回值。
34 |
35 | \5. pthread_cancel 终止当前线程。
36 |
37 | 代码语言:javascript
38 |
39 | 复制
40 |
41 | ```javascript
42 | #include
43 | #include
44 | #include "hello-thread.h"
45 | #define NUM_THREADS 5
46 |
47 | // 类似于 Java Runnable
48 | void *run(void *arg){
49 | // 取传入当前线程的参数
50 | char *thread_tag = (char*)arg;
51 |
52 | for (int i = 0; i < 5; ++i) {
53 | LOGD("%s thread %d", thread_tag, i);
54 | if (i == 4) {
55 | // 结束当前线程,参数为线程结束后的返回值
56 | pthread_exit(thread_tag);
57 | //pthread_cancel(); send a cancellation request to a thread
58 | }
59 | }
60 |
61 | return 0; // 线程正常执行完成后的返回值
62 | }
63 |
64 | void create_threads(){
65 | LOGD("Main thread");
66 | char tag_arr[][5] = {"No.1","No.2","No.3","No.4","No.5"};
67 |
68 | //线程 id ,用于区分线程,一个线程对应一个唯一的 id
69 | pthread_t tids[NUM_THREADS];
70 | for (int i = 0; i < NUM_THREADS; ++i) {
71 | // 创建线程,指定 run 方法,传入参数 tags[i]
72 | pthread_create(&tids[i], NULL, run, (void *) tag_arr[i]);
73 | }
74 |
75 | void *return_val[NUM_THREADS];
76 | for (int i = 0; i < NUM_THREADS; ++i) {
77 | // 阻塞当前线程,等待指定 tid 的线程结束,并获取线程返回值
78 | // join with a terminated thread
79 | pthread_join(tids[i], &return_val[i]);
80 | LOGD("thread %s terminated.", (char*)return_val[i]);
81 | }
82 | }
83 | ```
84 |
85 | 运行结果:
86 |
87 | 代码语言:javascript
88 |
89 | 复制
90 |
91 | ```javascript
92 | I/hello-thread: Main thread
93 | I/hello-thread: No.1 thread 0
94 | I/hello-thread: No.1 thread 1
95 | I/hello-thread: No.1 thread 2
96 | I/hello-thread: No.1 thread 3
97 | I/hello-thread: No.1 thread 4
98 | I/hello-thread: No.2 thread 0
99 | I/hello-thread: No.2 thread 1
100 | I/hello-thread: No.2 thread 2
101 | I/hello-thread: No.2 thread 3
102 | I/hello-thread: No.2 thread 4
103 | I/hello-thread: No.3 thread 0
104 | I/hello-thread: No.3 thread 1
105 | I/hello-thread: No.3 thread 2
106 | I/hello-thread: No.3 thread 3
107 | I/hello-thread: No.3 thread 4
108 | I/hello-thread: No.4 thread 0
109 | I/hello-thread: No.4 thread 1
110 | I/hello-thread: No.4 thread 2
111 | I/hello-thread: No.4 thread 3
112 | I/hello-thread: No.4 thread 4
113 | I/hello-thread: thread No.1 terminated.
114 | I/hello-thread: No.5 thread 0
115 | I/hello-thread: No.5 thread 1
116 | I/hello-thread: No.5 thread 2
117 | I/hello-thread: No.5 thread 3
118 | I/hello-thread: No.5 thread 4
119 | I/hello-thread: thread No.2 terminated.
120 | I/hello-thread: thread No.3 terminated.
121 | I/hello-thread: thread No.4 terminated.
122 | I/hello-thread: thread No.5 terminated.
123 | ```
124 |
125 | **3. POSIX 线程同步**
126 |
127 | 线程同步相关 API :
128 |
129 | \1. pthread_mutex_t 互斥锁。
130 |
131 | \2. pthread_mutex_init 初始化互斥锁,需传入互斥锁的指针。
132 |
133 | \3. pthread_mutex_destroy 销毁互斥锁,需传入互斥锁的指针。
134 |
135 | \4. pthread_mutex_lock 加锁,需传入互斥锁的指针。
136 |
137 | \5. pthread_mutex_unlock 解锁,需传入互斥锁的指针
138 |
139 | 代码语言:javascript
140 |
141 | 复制
142 |
143 | ```javascript
144 | #include
145 | #include
146 | #include "hello-thread.h"
147 | int g_count = 0;
148 |
149 | // 互斥锁
150 | pthread_mutex_t mutex;
151 |
152 | void *asyn_run(void *arg){
153 | // lock
154 | pthread_mutex_lock(&mutex);
155 |
156 | // 取传入当前线程的参数
157 | char *thread_tag = (char*)arg;
158 |
159 | for (int i = 0; i < 10; ++i) {
160 | // 休眠 200 ms
161 | usleep(200 * 1000);
162 | g_count ++;
163 | LOGD("%s thread %d, g_count = %d", thread_tag, i, g_count);
164 | }
165 |
166 | // unlock
167 | pthread_mutex_unlock(&mutex);
168 |
169 | return thread_tag; // 线程正常执行完成后的返回值
170 | }
171 |
172 | void syn_thread(){
173 | LOGD("Main thread");
174 |
175 | // 初始化互斥锁
176 | pthread_mutex_init(&mutex, NULL);
177 |
178 | pthread_t t1, t2;
179 |
180 | // 创建 2 个线程
181 | pthread_create(&t1, NULL, asyn_run, "No.1");
182 | pthread_create(&t2, NULL, asyn_run, "No.2");
183 |
184 | void *rtn_val[2];
185 | pthread_join(t1, &rtn_val[0]);
186 | pthread_join(t2, &rtn_val[1]);
187 | LOGD("thread %s terminated.", (char*)rtn_val[0]);
188 | LOGD("thread %s terminated.", (char*)rtn_val[1]);
189 |
190 | // 销毁互斥锁
191 | pthread_mutex_destroy(&mutex);
192 |
193 | }
194 | ```
195 |
196 | 运行结果:
197 |
198 | 代码语言:javascript
199 |
200 | 复制
201 |
202 | ```javascript
203 | I/hello-thread: No.1 thread 0, g_count = 1
204 | I/hello-thread: No.1 thread 1, g_count = 2
205 | I/hello-thread: No.1 thread 2, g_count = 3
206 | I/hello-thread: No.1 thread 3, g_count = 4
207 | I/hello-thread: No.1 thread 4, g_count = 5
208 | I/hello-thread: No.1 thread 5, g_count = 6
209 | I/hello-thread: No.1 thread 6, g_count = 7
210 | I/hello-thread: No.1 thread 7, g_count = 8
211 | I/hello-thread: No.1 thread 8, g_count = 9
212 | I/hello-thread: No.1 thread 9, g_count = 10
213 | I/hello-thread: No.2 thread 0, g_count = 11
214 | I/hello-thread: No.2 thread 1, g_count = 12
215 | I/hello-thread: No.2 thread 2, g_count = 13
216 | I/hello-thread: No.2 thread 3, g_count = 14
217 | I/hello-thread: No.2 thread 4, g_count = 15
218 | I/hello-thread: No.2 thread 5, g_count = 16
219 | I/hello-thread: No.2 thread 6, g_count = 17
220 | I/hello-thread: No.2 thread 7, g_count = 18
221 | I/hello-thread: No.2 thread 8, g_count = 19
222 | I/hello-thread: No.2 thread 9, g_count = 20
223 | I/hello-thread: thread No.1 terminated.
224 | I/hello-thread: thread No.2 terminated.
225 | ```
226 |
227 | **5. POSIX 线程间通信**
228 |
229 | 线程间通信相关 API :
230 |
231 | \1. pthread_cond_t 条件变量,条件变量是线程同步的一种手段,使 线程可以休眠等待某种条件出现。
232 |
233 | \2. pthread_cond_signal 发送一个信号给另外一个正在处于阻塞等 待状态的线程,原本这两个线程竞争同一个 mutex lock 。
234 |
235 | \3. pthread_cond_wait 使当前线程处于阻塞状态,直到接收到其他 线程发送对应的 condsignal 。
236 |
237 | \4. pthread_cond_init 初始化条件变量。
238 |
239 | \5. pthread_cond_destroy 销毁条件变量。
240 |
241 | 代码语言:javascript
242 |
243 | 复制
244 |
245 | ```javascript
246 | #include
247 | #include
248 | #include "hello-thread.h"
249 | // 共享数据
250 | volatile int shared_count = 0;
251 | pthread_mutex_t pthread_mutex;
252 |
253 | // 条件变量
254 | pthread_cond_t pthread_cond;
255 |
256 | void *producer(void *arg){
257 | char *tag = (char*)arg;
258 | for (;;) {
259 | pthread_mutex_lock(&pthread_mutex);
260 |
261 | // 生产者生产产品
262 | shared_count ++;
263 | LOGD("%s thread 生产产品, count = %d", tag, shared_count);
264 |
265 | // 通知消费者线程消费
266 | pthread_cond_signal(&pthread_cond);
267 |
268 | pthread_mutex_unlock(&pthread_mutex);
269 |
270 | // 休眠 200 ms
271 | usleep(200 * 1000);
272 | }
273 |
274 | return (void*)0;
275 | }
276 |
277 | void *consumer(void *arg){
278 | char* tag = (char*)arg;
279 | for(;;){
280 | pthread_mutex_lock(&pthread_mutex);
281 |
282 | while (shared_count == 0){
283 | // 当没有产品可以消费时,等待生产者生产(等待条件变量被唤醒,当前线程释放互斥锁)
284 | // 当被其他线程唤醒时,解除阻塞状态,重新申请获得互斥锁
285 | pthread_cond_wait(&pthread_cond, &pthread_mutex);
286 |
287 | }
288 |
289 | shared_count --;
290 | LOGD("%s thread 消费产品, count = %d", tag, shared_count);
291 |
292 | pthread_mutex_unlock(&pthread_mutex);
293 |
294 | // 休眠 500 ms
295 | usleep(500 * 1000);
296 | }
297 |
298 | return (void*)0;
299 |
300 | };
301 |
302 | // 线程间通信
303 | void communicate_thread(){
304 | pthread_mutex_init(&pthread_mutex, NULL);
305 |
306 | // 初始化条件变量
307 | pthread_cond_init(&pthread_cond, NULL);
308 |
309 | // 线程 id
310 | pthread_t producer_tid, consumer_tid;
311 |
312 | // 创建生产者线程
313 | pthread_create(&producer_tid, NULL, producer, "producer");
314 | // 创建消费者线程
315 | pthread_create(&consumer_tid, NULL, consumer, "consumer");
316 |
317 | // 等待线程结束
318 | pthread_join(producer_tid, NULL);
319 | pthread_join(consumer_tid, NULL);
320 |
321 | // 销毁互斥锁
322 | pthread_mutex_destroy(&pthread_mutex);
323 | // 销毁条件变量
324 | pthread_cond_destroy(&pthread_cond);
325 |
326 | }
327 | ```
328 |
329 | 运行结果:
330 |
331 | 代码语言:javascript
332 |
333 | 复制
334 |
335 | ```javascript
336 | I/hello-thread: producer thread 生产产品, count = 1
337 | I/hello-thread: consumer thread 消费产品, count = 0
338 | I/hello-thread: producer thread 生产产品, count = 1
339 | I/hello-thread: producer thread 生产产品, count = 2
340 | I/hello-thread: consumer thread 消费产品, count = 1
341 | I/hello-thread: producer thread 生产产品, count = 2
342 | I/hello-thread: producer thread 生产产品, count = 3
343 | I/hello-thread: consumer thread 消费产品, count = 2
344 | I/hello-thread: producer thread 生产产品, count = 3
345 | I/hello-thread: producer thread 生产产品, count = 4
346 | I/hello-thread: producer thread 生产产品, count = 5
347 | I/hello-thread: consumer thread 消费产品, count = 4
348 | I/hello-thread: producer thread 生产产品, count = 5
349 | I/hello-thread: producer thread 生产产品, count = 6
350 | I/hello-thread: consumer thread 消费产品, count = 5
351 | ......
352 | ```
353 |
354 | -- END --
355 |
--------------------------------------------------------------------------------
/How To Automate Mounting dev In Chroot Environments In Linux.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://ostechnix.com/auto-mount-dev-in-chroot/
2 |
3 |
4 |
5 |
6 |
7 | # How To Automate Mounting /dev In Chroot Environments In Linux
8 |
9 |
10 |
11 | If you’re using `mmdebstrap` to create minimal Debian-based systems, you might find it annoying to manually mount and unmount the `/dev` directory every time you use the chroot. The good news is, there are ways to automate this process! In this guide, we’ll show you how to make your workflow more efficient by **automatically mounting `/dev`** when you enter the chroot environment and unmounting it when you exit.
12 |
13 |
14 |
15 | ## Why Automate Mounting `/dev`?
16 |
17 | When you create a chroot environment, it doesn’t have access to the host system’s `/dev` directory by default. This can cause errors when running commands like `apt update` because programs need access to device files like `/dev/null`.
18 |
19 | ```
20 | [...]
21 | /usr/bin/apt-key: 95: cannot create /dev/null: Permission denied
22 | /usr/bin/apt-key: 95: cannot create /dev/null: Permission denied
23 | E: gpgv, gpgv2 or gpgv1 required for verification, but neither seems installed
24 | Err:3 http://deb.debian.org/debian bookworm-updates InRelease
25 | gpgv, gpgv2 or gpgv1 required for verification, but neither seems installed
26 | [...]
27 | ```
28 |
29 | You can solve this issue by **[manually mounting `/dev`](https://ostechnix.com/troubleshooting-mmdebstrap/)** ([[Troubleshooting mmdebstrap]]) every time you use the chroot. But it is tedious and time-consuming. Automating this process saves you effort and makes your workflow smoother.
30 |
31 | ## Solution 1: Use systemd-nspawn to Automate Mounting /dev in a Chroot
32 |
33 | **systemd-nspawn** is a command-line tool included in the systemd suite that allows you to create and run lightweight, isolated system containers on Linux systems. It provides a way to execute commands or even entire operating systems within a sandboxed environment.
34 |
35 |
36 |
37 | The `systemd-nspawn` tool can automatically handle mounting `/dev` and other directories.
38 |
39 |
40 |
41 | ### Step 1: Install `systemd-nspawn`
42 |
43 | On Debian-based systems, install it with:
44 |
45 | ```
46 | sudo apt update
47 | sudo apt install systemd-container
48 | ```
49 |
50 | ### Step 2: Enter the Chroot with `systemd-nspawn`
51 |
52 | Create a chroot environment using mmdebstrap:
53 |
54 | ```
55 | mmdebstrap --variant=minbase stable /tmp/debian-rootfs
56 | ```
57 |
58 | Next, enter the chroot using command:
59 |
60 | ```
61 | sudo systemd-nspawn -D /tmp/debian-rootfs
62 | ```
63 |
64 | `systemd-nspawn` automatically mounts `/dev`, `/proc`, and `/sys` inside the chroot. When you exit the chroot, it automatically unmounts these directories.
65 |
66 | ## Solution 2: Use Chrootmnt Script to Automatically Mount and Unmount /dev in Chroot Environments
67 |
68 | **[Chrootmnt](https://gist.github.com/ostechnix/7ca184e32caf6f4e2db8eab9dbeb8259)** is a Bash script to mount and unmount `/dev` inside a chroot environment, ensuring seamless device access and automatic cleanup for secure Linux system management.
69 |
70 |
71 |
72 | **Key Features**
73 |
74 | 1. **Flexible Inputs:** Works with any chroot directory and command.
75 | 2. **Error Handling:** Prevents failures caused by missing directories or improper arguments.
76 | 3. **Automatic Cleanup:** Avoids leaving mounted resources if interrupted.
77 | 4. **Pseudo-Terminal Support:** Ensures compatibility with interactive tools like SSH, screen, and tmux.
78 |
79 | Chrootmnt script is available in our **[OSTechNix GitHub Gist](https://gist.github.com/ostechnix)** page. You can freely download and modify it as you wish.
80 |
81 | ### Step 1: Create the Script
82 |
83 | Save the following script as `chrootmnt.sh`:
84 |
85 | ```
86 | #!/usr/bin/env bash
87 |
88 | # ------------------------------------------------------------------
89 | # Script Name: chrootmnt.sh
90 | # Description: A Bash script to mount and unmount /dev
91 | # inside a chroot environment
92 | # Website: https://gist.github.com/ostechnix
93 | # Version: 1.0
94 | # Usage: ./chrootmnt.sh /path/to/chroot command args
95 | # ------------------------------------------------------------------
96 |
97 | # Validate input
98 | if [ $# -lt 2 ]; then
99 | echo "Usage: $0 /path/to/chroot command [args...]"
100 | exit 1
101 | fi
102 |
103 | # Path to the chroot directory
104 | CHROOT_DIR="$1"
105 | shift # Remove the first argument (chroot path)
106 |
107 | # Ensure the chroot directory exists
108 | if [ ! -d "$CHROOT_DIR" ]; then
109 | echo "Error: Chroot directory $CHROOT_DIR does not exist."
110 | exit 1
111 | fi
112 |
113 | # Mount /dev and /dev/pts
114 | sudo mount --bind /dev "$CHROOT_DIR/dev"
115 | sudo mount --bind /dev/pts "$CHROOT_DIR/dev/pts"
116 |
117 | # Handle unmounting on exit
118 | cleanup() {
119 | sudo umount "$CHROOT_DIR/dev/pts"
120 | sudo umount "$CHROOT_DIR/dev"
121 | }
122 | trap cleanup EXIT
123 |
124 | # Enter the chroot
125 | sudo chroot "$CHROOT_DIR" "$@"
126 | ```
127 |
128 |
129 |
130 | Here is a step-by-step explanation of how the script works:
131 |
132 | **1. Input Validation**
133 |
134 | ```
135 | if [ $# -lt 2 ]; then
136 | echo "Usage: $0 /path/to/chroot command [args...]"
137 | exit 1
138 | fi
139 | ```
140 |
141 |
142 |
143 | - Ensures the user provides
144 |
145 |
146 |
147 | at least two arguments
148 |
149 | :
150 |
151 | 1. The path to the chroot directory.
152 | 2. A command (e.g., `/bin/bash`) to execute inside the chroot.
153 |
154 | - If arguments are missing, it displays usage instructions and exits.
155 |
156 | **2. Store Arguments**
157 |
158 | ```
159 | CHROOT_DIR="$1"
160 | shift # Remove the first argument (chroot path)
161 | ```
162 |
163 | - Stores the **chroot directory path** in `CHROOT_DIR`.
164 |
165 | - Uses
166 |
167 |
168 |
169 | ```
170 | shift
171 | ```
172 |
173 |
174 |
175 | to remove this argument, leaving only the command and its optional arguments.
176 |
177 | - Example: If input is:
178 |
179 |
180 |
181 | ```
182 | ./chrootmnt.sh /tmp/debian-rootfs /bin/bash
183 | ```
184 |
185 | - `CHROOT_DIR` = `/tmp/debian-rootfs`
186 | - Remaining args (`/bin/bash`) are passed to `chroot`.
187 |
188 | **3. Directory Check**
189 |
190 | ```
191 | if [ ! -d "$CHROOT_DIR" ]; then
192 | echo "Error: Chroot directory $CHROOT_DIR does not exist."
193 | exit 1
194 | fi
195 | ```
196 |
197 | - Confirms the specified chroot directory exists.
198 | - If the directory is missing, it prints an error and exits.
199 |
200 | **4. Mount `/dev` and `/dev/pts`**
201 |
202 | ```
203 | sudo mount --bind /dev "$CHROOT_DIR/dev"
204 | sudo mount --bind /dev/pts "$CHROOT_DIR/dev/pts"
205 | ```
206 |
207 | - Binds the host's `/dev` and `/dev/pts`
208 |
209 |
210 |
211 | inside the chroot.
212 |
213 | - `/dev`: Provides device files (e.g., `/dev/null`, `/dev/tty`).
214 | - `/dev/pts`: Supports pseudo-terminals (used by programs like SSH and screen).
215 |
216 | - Ensures programs inside the chroot can access devices and terminals correctly.
217 |
218 | **5. Cleanup Function**
219 |
220 | ```
221 | cleanup() {
222 | sudo umount "$CHROOT_DIR/dev/pts"
223 | sudo umount "$CHROOT_DIR/dev"
224 | }
225 | trap cleanup EXIT
226 | ```
227 |
228 | - **Defines a function** (`cleanup`) that unmounts `/dev` and `/dev/pts`.
229 |
230 | - Registers this function to run
231 |
232 |
233 |
234 | automatically when the script exits
235 |
236 |
237 |
238 | (successful or error).
239 |
240 | - Prevents leaving stale mounts if something goes wrong.
241 |
242 | **6. Enter the Chroot**
243 |
244 | ```
245 | sudo chroot "$CHROOT_DIR" "$@"
246 | ```
247 |
248 | - Uses the `chroot` command to switch to the specified root directory (`CHROOT_DIR`).
249 |
250 | - Executes the command provided as additional arguments (
251 |
252 | ```
253 | $@
254 | ```
255 |
256 | ).
257 |
258 | - Example:
259 |
260 |
261 |
262 | ```
263 | ./chrootmnt.sh /tmp/debian-rootfs /bin/bash
264 | ```
265 |
266 | - Executes `/bin/bash` inside the chroot.
267 |
268 |
269 |
270 | **7. Automatic Cleanup**
271 |
272 | - When the
273 |
274 |
275 |
276 | ```
277 | chroot
278 | ```
279 |
280 |
281 |
282 | session ends (either normally or due to an error), the script automatically:
283 |
284 | 1. Unmounts `/dev/pts`.
285 | 2. Unmounts `/dev`.
286 |
287 | ### Step 2: Make the Script Executable
288 |
289 | Run the following command to make the script executable:
290 |
291 | ```
292 | chmod +x chrootmnt.sh
293 | ```
294 |
295 | ### Step 3: Use the Script
296 |
297 | First, make sure you created the chroot environment:
298 |
299 | ```
300 | mmdebstrap --variant=minbase stable /tmp/debian-rootfs
301 | ```
302 |
303 | Now, Instead of using `sudo chroot /tmp/debian-rootfs`, use the script to enter the chroot:
304 |
305 | **Start a shell inside `/tmp/debian-rootfs`:**
306 |
307 | ```
308 | ./chrootmnt.sh /tmp/debian-rootfs /bin/bash
309 | ```
310 |
311 | **Run a command (e.g., `ls -l /`) inside the chroot:**
312 |
313 |
314 |
315 | ```
316 | ./chrootmnt.sh /tmp/debian-rootfs ls -l /
317 | ```
318 |
319 | Just make sure you have entered the correct path of your chroot environment. In this case, the chroot directory is `/tmp/debian-tootfs`. Replace this with your own.
320 |
321 | ## Which Solution Should You Use?
322 |
323 | - **`systemd-nspawn`**: Best for advanced users who want a container-like experience.
324 | - **Chrootmnt Script**: Best for simplicity and automation.
325 |
326 | ## Conclusion
327 |
328 | Manually mounting and unmounting `/dev` every time you use the chroot is not productive. By using the `systemd-nspawn` or a wrapper script, you can automate this process and save time. Choose the method that best fits your workflow, and enjoy a smoother experience with `mmdebstrap`!
329 |
--------------------------------------------------------------------------------
/Linux系统入门系列之三:初识Bash.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://mp.weixin.qq.com/s/RSfrvmk7OF2ytwsmp7fGOw
2 |
3 |
4 |
5 |
6 |
7 | # Linux系统入门系列之三:初识Bash
8 |
9 |
10 |
11 | 
12 |
13 | 
14 |
15 | 事物最外面的一层我们称之为壳(Shell),例如贝壳、地壳。壳是事物与观察者信息交流的媒介,观察者通过壳可以直观地感受、描述事物。计算机同样是如此,普通用户无法直接操作计算机的内核,也需要借助Shell这个媒介来与计算机内核进行交互。不同的操作系统拥有不同的Shell,对于Windows系统,图形界面的Windows即是其shell;而对于Linux系统,其Shell称之为Bash。
16 |
17 | ——初识Bash
18 |
19 | ## 1.Bash变量
20 |
21 | ### ⑴环境变量
22 |
23 | Bash内置的用户属性变量多属于环境变量,类似于全局变量,例如PATH、HOME、MAIL等,环境变量只能通过修改用户配置文件(~/.bashrc或~/.bash_profile)来进行修改。环境变量通常以大写字符来表示,可以使用echo$命令来显示变量,示例如下:
24 |
25 | 
26 |
27 | 我们可以使用env命令来查看系统默认的环境变量:
28 |
29 | 
30 |
31 | 其中有些环境变量比较常用,例如RANDOM变量是常用的随机数生成变量(0~32767),示例如下:
32 |
33 | 
34 |
35 | 此外,环境变量PATH非常有用,可以添加常用软件的绝对路径来方便软件的调用;环境变量?(是的,就是一个问号)为上一个执行的命令所传回的值,一般成功执行,传回0,发生错误,就会回传错误代码。
36 |
37 | ### ⑵自定义变量
38 |
39 | 用户可以根据自己需要自定义变量,属于局部变量,使用“=”进行赋值(等号两边不能有空格),变量名由数字和字母组成且以字母开头,赋值内容若包含空格等特殊字符需加双引号,双引号内也可以引用其他变量,特殊字符可以使用反斜杠“\”来转义。可以使用echo命令来显示变量,示例如下:
40 |
41 | 
42 |
43 | 可以使用declare来声明变量为数值(-i)类型,例如生成个位数的随机数:
44 |
45 | 
46 |
47 |
48 |
49 | 如果不事先声明,赋值会默认是字符串:
50 |
51 | 
52 |
53 | 取消已经赋值的变量可以使用unset命令,示例如下:
54 |
55 | 
56 |
57 | 一般一个变量只能在一个子程序中运行,export命令可以将变量变为环境变量,从而可以在其它子程序中运行,示例如下:
58 |
59 | 
60 |
61 | 使用set命令可以查看当前环境所有变量(包含环境变量和自定义变量):
62 |
63 | 
64 |
65 | 如果要实现计算机与用户的交互,让用户用键盘来输入变量内容,可以使用read命令,示例如下:
66 |
67 | 
68 |
69 | 还可以设定提示字符以及限定输入时间:
70 |
71 | 
72 |
73 |
74 |
75 | ### ⑶Bash数组
76 |
77 | 数组也即向量,可以通过变量名与index的方式赋值,示例如下:
78 |
79 |
80 |
81 | 
82 |
83 | 还可以通过“@”作为index提取所有变量:
84 |
85 | 
86 |
87 | 还可以直接通过括号来进行赋值,不同元素间空格隔开:
88 |
89 | 
90 |
91 | 注意,默认的index是从0开始的!
92 |
93 | ### ⑷变量运算
94 |
95 | 在赋值的时候,可以直接使用“$”或“${}”来引用变量和数组,可以使用“$()”引用命令结果,使用,示例如下:
96 |
97 | 
98 |
99 | 变量可以直接累加:
100 |
101 | 
102 |
103 | 可以通过“#”来从左到右删除变量内容,通过“%”来从右到左删除变量内容,除标记字符外其他字符可以通过“*”(多个字符)或“?”(单个字符)来指代:
104 |
105 | 
106 |
107 | 可以通过“/”将旧字符串替换为新的字符串:
108 |
109 | 
110 |
111 | 假如标记字符存在于多处,“#”为删除最短字符,“##”为删除最长字符,同样适用于“%”和“/”,示例如下:
112 |
113 | 
114 |
115 | 通过shell脚本,也可以引用其他软件和脚本的运行结果来进行变量赋值与运算:
116 |
117 | 
118 |
119 |
120 |
121 | 
122 |
123 | 在变量运算的时候,可以通过declare命令声明变量类型,不同类型变量类型例如字符串和数值,其运算规则不同,具体如下所示:
124 |
125 | 
126 |
127 | 其他参数选项如下所示:
128 |
129 | ```
130 | -a:声明为数组;-x:相当于命令export;-r:声明为只读变量。
131 | ```
132 |
133 | 在Bash中,任何命令(包括管道命令)加上反单引号``之后都可以直接作为变量引用,其值为命令运行结果,可以为变量赋值,例如我们列出目录下所有txt文档并将其储存在变量txt里面:
134 |
135 | 
136 |
137 | 这一点对于以后的Shell脚本编写非常有用。下面我们可以列出某文件的文件名以及其行数:
138 |
139 | 
140 |
141 | 利用这种用法可以很方便的计算序列数目。
142 |
143 | ## 2.文本编辑
144 |
145 | ### ⑴基本编辑
146 |
147 | Linux平台的大多数文件均是ASCII的纯文本文件,在Linux中Vi/Vim是强大的文本处理工具,Vim可以看成Vi的升级版。Vim有三种模式:一般模式、编辑模式、命令行模式。使用vim创建或打开已有文本文件,示例如下:
148 |
149 | 
150 |
151 | 此时即进入一般模式,这时候可以进行删除、复制等操作(最好不要复制),但是无法输入内容:
152 |
153 | 
154 |
155 | 当按键盘上“a”、“i”键,下方显示“INSERT”,开始进入编辑模式:
156 |
157 | 
158 |
159 | 可以使用键盘输入,也可以从其它文件(txt、word、excel等)中直接复制粘贴过去:
160 |
161 | 
162 |
163 | 编辑完毕后,按“Esc”键退出编辑模式,又进入一般模式。当输入“:”、“/”“?”是便会移动到最下方的命令行进入命令行模式。输入:wq命令按回车键保存并退出。如果保存还未命名的文件,:wq空格后输入文件名(若已命名则是另存为),若是不想保存修改,则输入:q!命令。
164 |
165 | ### ⑵文本处理
166 |
167 | 在一般模式里,x/X为向后/前删除一个字符,yy、dd为复制、删除光标所在行,p为将复制内容粘贴到光标下一行。在命令行模式里,Vim有很强大的文本处理功能,可以对文本进行批量处理,具体如下。
168 |
169 | 输入“/+内容”或者“?+内容”来搜索想查找的内容:
170 |
171 | 
172 |
173 | 按键“n”或者“N”(即Shift+n)可以向下或向上查找内容。在命令行进行查找替换。查找第2行到第4行的第一个is并替换为ia,其命令为:2,4s/is/ia/:
174 |
175 |  
176 |
177 | 其中s为替换的意思,若是第三行全部is替换为ia,则为:2,4s/is/ia/g:
178 |
179 |  
180 |
181 | 若是最后一行行号可以用“$”来表示,若是删除,也可以实现:
182 |
183 |  
184 |
185 | 此外,输入:set nu/nonu可以设置显示/不现实行号:
186 |
187 | 
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/How to install Linux on Windows with WSL.md:
--------------------------------------------------------------------------------
1 | 原文链接:https://learn.microsoft.com/en-us/windows/wsl/install
2 |
3 |
4 |
5 | # How to install Linux on Windows with WSL
6 |
7 |
8 |
9 | ## In this article
10 |
11 | 1. [Prerequisites](https://learn.microsoft.com/en-us/windows/wsl/install#prerequisites)
12 | 2. [Install WSL command](https://learn.microsoft.com/en-us/windows/wsl/install#install-wsl-command)
13 | 3. [Change the default Linux distribution installed](https://learn.microsoft.com/en-us/windows/wsl/install#change-the-default-linux-distribution-installed)
14 | 4. [Set up your Linux user info](https://learn.microsoft.com/en-us/windows/wsl/install#set-up-your-linux-user-info)
15 | 5. [Set up and best practices](https://learn.microsoft.com/en-us/windows/wsl/install#set-up-and-best-practices)
16 | 6. [Check which version of WSL you are running](https://learn.microsoft.com/en-us/windows/wsl/install#check-which-version-of-wsl-you-are-running)
17 | 7. [Upgrade version from WSL 1 to WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install#upgrade-version-from-wsl-1-to-wsl-2)
18 | 8. [Ways to run multiple Linux distributions with WSL](https://learn.microsoft.com/en-us/windows/wsl/install#ways-to-run-multiple-linux-distributions-with-wsl)
19 | 9. [Want to try the latest WSL preview features?](https://learn.microsoft.com/en-us/windows/wsl/install#want-to-try-the-latest-wsl-preview-features)
20 | 10. [Additional resources](https://learn.microsoft.com/en-us/windows/wsl/install#additional-resources)
21 |
22 | Developers can access the power of both Windows and Linux at the same time on a Windows machine. The Windows Subsystem for Linux (WSL) lets developers install a Linux distribution (such as Ubuntu, OpenSUSE, Kali, Debian, Arch Linux, etc) and use Linux applications, utilities, and Bash command-line tools directly on Windows, unmodified, without the overhead of a traditional virtual machine or dualboot setup.
23 |
24 |
25 |
26 | ## Prerequisites
27 |
28 | You must be running Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11 to use the commands below. If you are on earlier versions please see [the manual install page](https://learn.microsoft.com/en-us/windows/wsl/install-manual).
29 |
30 |
31 |
32 | ## Install WSL command
33 |
34 | You can now install everything you need to run WSL with a single command. Open PowerShell or Windows Command Prompt in **administrator** mode by right-clicking and selecting "Run as administrator", enter the wsl --install command, then restart your machine.
35 |
36 | PowerShellCopy
37 |
38 | ```powershell
39 | wsl --install
40 | ```
41 |
42 | This command will enable the features necessary to run WSL and install the Ubuntu distribution of Linux. ([This default distribution can be changed](https://learn.microsoft.com/en-us/windows/wsl/basic-commands#install)).
43 |
44 | If you're running an older build, or just prefer not to use the install command and would like step-by-step directions, see **[WSL manual installation steps for older versions](https://learn.microsoft.com/en-us/windows/wsl/install-manual)**.
45 |
46 | The first time you launch a newly installed Linux distribution, a console window will open and you'll be asked to wait for files to de-compress and be stored on your machine. All future launches should take less than a second.
47 |
48 | Note
49 |
50 | The above command only works if WSL is not installed at all. If you run `wsl --install` and see the WSL help text, please try running `wsl --list --online` to see a list of available distros and run `wsl --install -d ` to install a distro. To uninstall WSL, see [Uninstall legacy version of WSL](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting#uninstall-legacy-version-of-wsl) or [unregister or uninstall a Linux distribution](https://learn.microsoft.com/en-us/windows/wsl/basic-commands#unregister-or-uninstall-a-linux-distribution).
51 |
52 |
53 |
54 | ## Change the default Linux distribution installed
55 |
56 | By default, the installed Linux distribution will be Ubuntu. This can be changed using the `-d` flag.
57 |
58 | - To change the distribution installed, enter: `wsl --install -d `. Replace `` with the name of the distribution you would like to install.
59 | - To see a list of available Linux distributions available for download through the online store, enter: `wsl --list --online` or `wsl -l -o`.
60 | - To install additional Linux distributions after the initial install, you may also use the command: `wsl --install -d `.
61 |
62 | Tip
63 |
64 | If you want to install additional distributions from inside a Linux/Bash command line (rather than from PowerShell or Command Prompt), you must use .exe in the command: `wsl.exe --install -d ` or to list available distributions: `wsl.exe -l -o`.
65 |
66 | If you run into an issue during the install process, check the [installation section of the troubleshooting guide](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting#installation-issues).
67 |
68 | To install a Linux distribution that is not listed as available, you can [import any Linux distribution](https://learn.microsoft.com/en-us/windows/wsl/use-custom-distro) using a TAR file. Or in some cases, [as with Arch Linux](https://wsldl-pg.github.io/ArchW-docs/How-to-Setup/), you can install using an `.appx` file. You can also create your own [custom Linux distribution](https://learn.microsoft.com/en-us/windows/wsl/build-custom-distro) to use with WSL.
69 |
70 |
71 |
72 | ## Set up your Linux user info
73 |
74 | Once you have installed WSL, you will need to create a user account and password for your newly installed Linux distribution. See the [Best practices for setting up a WSL development environment](https://learn.microsoft.com/en-us/windows/wsl/setup/environment#set-up-your-linux-username-and-password) guide to learn more.
75 |
76 |
77 |
78 | ## Set up and best practices
79 |
80 | We recommend following our [Best practices for setting up a WSL development environment](https://learn.microsoft.com/en-us/windows/wsl/setup/environment) guide for a step-by-step walk-through of how to set up a user name and password for your installed Linux distribution(s), using basic WSL commands, installing and customizing Windows Terminal, set up for Git version control, code editing and debugging using the VS Code remote server, good practices for file storage, setting up a database, mounting an external drive, setting up GPU acceleration, and more.
81 |
82 |
83 |
84 | ## Check which version of WSL you are running
85 |
86 | You can list your installed Linux distributions and check the version of WSL each is set to by entering the command: `wsl -l -v` in PowerShell or Windows Command Prompt.
87 |
88 | To set the default version to WSL 1 or WSL 2 when a new Linux distribution is installed, use the command: `wsl --set-default-version `, replacing `` with either 1 or 2.
89 |
90 | To set the default Linux distribution used with the `wsl` command, enter: `wsl -s ` or `wsl --set-default `, replacing `` with the name of the Linux distribution you would like to use. For example, from PowerShell/CMD, enter: `wsl -s Debian` to set the default distribution to Debian. Now running `wsl npm init` from Powershell will run the `npm init` command in Debian.
91 |
92 | To run a specific wsl distribution from within PowerShell or Windows Command Prompt without changing your default distribution, use the command: `wsl -d `, replacing `` with the name of the distribution you want to use.
93 |
94 | Learn more in the guide to [Basic commands for WSL](https://learn.microsoft.com/en-us/windows/wsl/basic-commands).
95 |
96 |
97 |
98 | ## Upgrade version from WSL 1 to WSL 2
99 |
100 | New Linux installations, installed using the `wsl --install` command, will be set to WSL 2 by default.
101 |
102 | The `wsl --set-version` command can be used to downgrade from WSL 2 to WSL 1 or to update previously installed Linux distributions from WSL 1 to WSL 2.
103 |
104 | To see whether your Linux distribution is set to WSL 1 or WSL 2, use the command: `wsl -l -v`.
105 |
106 | To change versions, use the command: `wsl --set-version 2` replacing `` with the name of the Linux distribution that you want to update. For example, `wsl --set-version Ubuntu-20.04 2` will set your Ubuntu 20.04 distribution to use WSL 2.
107 |
108 | If you manually installed WSL prior to the `wsl --install` command being available, you may also need to [enable the virtual machine optional component](https://learn.microsoft.com/en-us/windows/wsl/install-manual#step-3---enable-virtual-machine-feature) used by WSL 2 and [install the kernel package](https://learn.microsoft.com/en-us/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package) if you haven't already done so.
109 |
110 | To learn more, see the [Command reference for WSL](https://learn.microsoft.com/en-us/windows/wsl/basic-commands) for a list of WSL commands, [Comparing WSL 1 and WSL 2](https://learn.microsoft.com/en-us/windows/wsl/compare-versions) for guidance on which to use for your work scenario, or [Best practices for setting up a WSL development environment](https://learn.microsoft.com/en-us/windows/wsl/setup/environment) for general guidance on setting up a good development workflow with WSL.
111 |
112 |
113 |
114 | ## Ways to run multiple Linux distributions with WSL
115 |
116 | WSL supports running as many different Linux distributions as you would like to install. This can include choosing distributions from the [Microsoft Store](https://aka.ms/wslstore), [importing a custom distribution](https://learn.microsoft.com/en-us/windows/wsl/use-custom-distro), or [building your own custom distribution](https://learn.microsoft.com/en-us/windows/wsl/build-custom-distro).
117 |
118 | There are several ways to run your Linux distributions once installed:
119 |
120 | - [Install Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/get-started) ***(Recommended)*** Using Windows Terminal supports as many command lines as you would like to install and enables you to open them in multiple tabs or window panes and quickly switch between multiple Linux distributions or other command lines (PowerShell, Command Prompt, Azure CLI, etc). You can fully customize your terminal with unique color schemes, font styles, sizes, background images, and custom keyboard shortcuts. [Learn more.](https://learn.microsoft.com/en-us/windows/terminal)
121 | - You can directly open your Linux distribution by visiting the Windows Start menu and typing the name of your installed distributions. For example: "Ubuntu". This will open Ubuntu in its own console window.
122 | - From Windows Command Prompt or PowerShell, you can enter the name of your installed distribution. For example: `ubuntu`
123 | - From Windows Command Prompt or PowerShell, you can open your default Linux distribution inside your current command line, by entering: `wsl.exe`.
124 | - From Windows Command Prompt or PowerShell, you can use your default Linux distribution inside your current command line, without entering a new one, by entering:`wsl [command]`. Replacing `[command]` with a WSL command, such as: `wsl -l -v` to list installed distributions or `wsl pwd` to see where the current directory path is mounted in wsl. From PowerShell, the command `get-date` will provide the date from the Windows file system and `wsl date` will provide the date from the Linux file system.
125 |
126 | The method you select should depend on what you're doing. If you've opened a WSL command line within a Windows Prompt or PowerShell window and want to exit, enter the command: `exit`.
127 |
128 |
129 |
130 | ## Want to try the latest WSL preview features?
131 |
132 | Try the most recent features or updates to WSL by joining the [Windows Insiders Program](https://insider.windows.com/getting-started). Once you have joined Windows Insiders, you can choose the channel you would like to receive preview builds from inside the Windows settings menu to automatically receive any WSL updates or preview features associated with that build. You can choose from:
133 |
134 | - Dev channel: Most recent updates, but low stability.
135 | - Beta channel: Ideal for early adopters, more reliable builds than the Dev channel.
136 | - Release Preview channel: Preview fixes and key features on the next version of Windows just before its available to the general public.
137 |
138 | If you prefer not switching your Windows installation to a preview channel, you can still test the latest preview of WSL by issuing the command: `wsl --update --pre-release`. For more information check the [WSL Releases page on GitHub](https://github.com/Microsoft/WSL/releases).
139 |
--------------------------------------------------------------------------------
/Shell脚本:常用100个shell命令使用讲解题.md:
--------------------------------------------------------------------------------
1 | # Shell脚本:常用100个shell命令使用讲解题
2 |
3 |
4 |
5 | 在大多数的Linux和Unix系统、及其他类Unix系统中,Shell是用户与操作系统内核交互的主要方式。作为一种强大的命令行解释器,它也支持编程功能,用户可以写脚本来处理各种任务。
6 |
7 | 无论你是新手还是专业人士,掌握Shell命令都是必不可少的技能。在这篇文章中,我将逐个解读和展示Shell脚本中最常用的100个命令,并为每个命令提供实际的例子。
8 |
9 | ------
10 |
11 | # 目录
12 |
13 | - 文件操作命令
14 | - 搜索命令
15 | - 目录操作命令
16 | - 权限操作命令
17 | - 网络操作命令
18 | - 进程和系统控制命令
19 | - 文本操作命令
20 | - 压缩与解压命令
21 | - 磁盘使用管理命令
22 | - 包管理命令
23 | - 进程管理命令
24 | - 环境变量命令
25 | - 系统信息发布命令
26 | - 系统控制命令
27 | - 文本编辑命令
28 | - 其他有用命令
29 |
30 | ------
31 |
32 | # 文件操作命令
33 |
34 | 以下是在Linux系统中操作文件的一些常用命令:
35 |
36 | 1. ls:列出目录的内容
37 |
38 | ```
39 | ls /home
40 | ```
41 |
42 | 1. cd:改变目录
43 |
44 | ```
45 | cd /home/user/Documents
46 | ```
47 |
48 | 1. pwd:打印当前工作目录
49 |
50 | ```
51 | pwd
52 | ```
53 |
54 | 1. cat:查看文件内容
55 |
56 | ```
57 | cat /etc/passwd
58 | ```
59 |
60 | 1. more:分页查看文件内容
61 |
62 | ```
63 | more /var/log/syslog
64 | ```
65 |
66 | 1. less:反向分页查看文件内容
67 |
68 | ```
69 | less /var/log/syslog
70 | ```
71 |
72 | 1. touch:创建一个空文件或更改文件的访问和修改时间
73 |
74 | ```
75 | touch /home/user/newfile.txt
76 | ```
77 |
78 | 1. cp:复制文件或目录
79 |
80 | ```
81 | cp /home/user/file.txt /home/user/Documents
82 | ```
83 |
84 | 1. mv:移动或重命名文件或目录
85 |
86 | ```
87 | mv /home/user/file.txt /home/user/Documents/newfile.txt
88 | ```
89 |
90 | 1. rm:删除文件或目录
91 |
92 | ```
93 | rm /home/user/unwantedfile.txt
94 | ```
95 |
96 | 1. find:在文件系统中搜索文件或目录
97 |
98 | ```
99 | find / -name "*.log"
100 | ```
101 |
102 | 1. grep:在文件中搜索具有特定模式的行
103 |
104 | ```
105 | grep "error" /var/log/syslog
106 | ```
107 |
108 | 1. head:输出文件的开始部分
109 |
110 | ```
111 | head -n 10 /var/log/syslog
112 | ```
113 |
114 | 1. tail:输出文件的尾部
115 |
116 | ```
117 | tail -n 20 /var/log/syslog
118 | ```
119 |
120 | 1. sort:对文本文件的行进行排序
121 |
122 | ```
123 | sort /etc/passwd
124 | ```
125 |
126 | 1. wc:计算字数、行数和字节数
127 |
128 | ```
129 | wc /var/log/syslog
130 | ```
131 |
132 | 1. cut:从文件的每一行中剪切字节、字符和字段
133 |
134 | ```
135 | cut -d: -f1 /etc/passwd
136 | ```
137 |
138 | 1. nano,vi,emacs:常用的文本编辑器
139 |
140 | ```
141 | nano /home/user/file.txt
142 | vi /home/user/file.txt
143 | emacs /home/user/file.txt
144 | ```
145 |
146 | 1. paste:合并文件的行。
147 |
148 | ```
149 | paste file1.txt file2.txt
150 | ```
151 |
152 | ------
153 |
154 | # 搜索命令
155 |
156 | 以下命令可以帮助你搜索文件或文本:
157 |
158 | 1. find:在文件系统中搜索文件或目录。
159 |
160 | ```
161 | find / -name "*.log"
162 | ```
163 |
164 | 1. grep:在文本文件中搜索决定的文本模式。
165 |
166 | ```
167 | grep "error" /var/log/syslog
168 | ```
169 |
170 | 1. locate:基于文件名在数据库中快速找到文件。
171 |
172 | ```
173 | locate myFile.txt
174 | ```
175 |
176 | 1. which:返回可执行文件的路径。
177 |
178 | ```
179 | which java
180 | ```
181 |
182 | 1. ack:特别为程序员设计的一款文件搜索工具。默认会忽略多数版本控制文件夹(如.git, .svn等)的内容。
183 |
184 | ```
185 | ack "your_search_term"
186 | ```
187 |
188 | 1. ag(The Silver Searcher):比ack更快的代码搜索工具,同样默认忽略 .git 等版本控制文件夹中的内容。
189 |
190 | ```
191 | ag "your_search_term"
192 | ```
193 |
194 | 1. whereis:此命令可用于查找二进制程序、源文件、手册页以及其他文件的位置。
195 |
196 | ```
197 | whereis ls
198 | ```
199 |
200 | 1. type:此命令用于确定某个命令是内部 shell 命令、可执行文件还是别名。
201 |
202 | ```
203 | type pwd
204 | ```
205 |
206 | 1. apropos:如果你只记得关于某个命令的部分信息,你可以使用 apropos 命令来搜索帮助手册中的命令描述。
207 |
208 | ```
209 | apropos partition
210 | ```
211 |
212 | 1. alias:如果你经常使用某些 Linux 命令,你可以使用 alias 命令为这些常用命令创建一个短名,以提升你的工作效率。
213 |
214 | ```
215 | alias l='ls -al'
216 | ```
217 |
218 | ------
219 |
220 | # 目录操作命令
221 |
222 | 以下是在Linux系统中操作目录的一些常用命令:
223 |
224 | 1. mkdir:创建一个新的目录
225 |
226 | ```
227 | mkdir /home/user/new_directory
228 | ```
229 |
230 | 1. rmdir:删除一个空目录
231 |
232 | ```
233 | rmdir /home/user/empty_directory
234 | ```
235 |
236 | 1. tree:以树形结构列出目录的内容
237 |
238 | ```
239 | tree /home/user/
240 | ```
241 |
242 | 1. du:估计文件和目录的磁盘使用空间
243 |
244 | ```
245 | du -sh /home/user/Documents
246 | ```
247 |
248 | 1. df:显示磁盘使用空间
249 |
250 | ```
251 | df -h
252 | ```
253 |
254 | ------
255 |
256 | # 权限操作命令
257 |
258 | 在Linux系统中,文件和目录的访问可以通过权限操作命令进行控制:
259 |
260 | 1. chmod:更改文件或目录的权限
261 |
262 | ```
263 | chmod 755 /home/user/file.txt
264 | 表示设置文件的主用户有读,写和执行权限(rwx = 7),同组的用户和其他用户有读和执行权限(rx = 5)。
265 | ```
266 |
267 | 1. chown:更改文件或目录的所有者和所属的组
268 |
269 | ```
270 | chown newuser:newgroup /home/user/file.txt
271 | 表示将/home/user/file.txt的所有者更改为newuser,所属的组更改为newgroup。
272 | ```
273 |
274 | 1. chgrp:更改文件或目录的所属组
275 |
276 | ```
277 | chgrp newgroup /home/user/file.txt
278 | 表示将/home/user/file.txt的所属的组更改为newgroup。
279 | ```
280 |
281 | ------
282 |
283 | # 网络操作命令
284 |
285 | 以下是在Linux系统中与网络相关的一些常用命令:
286 |
287 | 1. ping:发送网络请求以测试网络连接
288 |
289 | ```
290 | ping www.google.com
291 | ```
292 |
293 | 1. ifconfig:显示或配置网络接口
294 |
295 | ```
296 | ifconfig eth0
297 | ```
298 |
299 | 1. netstat:显示网络连接、路由表等网络状态信息
300 |
301 | ```
302 | netstat -ntlp
303 | ```
304 |
305 | 1. ssh:远程登录或执行远程命令
306 |
307 | ```
308 | ssh user@remote_host
309 | ```
310 |
311 | 1. scp:在本地和远程系统之间安全地复制文件
312 |
313 | ```
314 | scp /path/to/file user@remote_host:/remote/path/
315 | ```
316 |
317 | 1. curl:获取网络资源
318 |
319 | ```
320 | curl www.google.com
321 | ```
322 |
323 | 1. telnet:远程登录工具
324 |
325 | ```
326 | telnet remote_host 23
327 | ```
328 |
329 | 1. nslookup:查询 DNS 名称服务器的记录
330 |
331 | ```
332 | nslookup www.google.com
333 | ```
334 |
335 | 1. ftp:在本地主机和FTP服务器之间建立FTP连接。
336 |
337 | ```
338 | ftp ftp_server
339 | ```
340 |
341 | 1. wget:获取网络资源
342 |
343 | ```
344 | wget www.google.com -o google.html
345 | ```
346 |
347 | ------
348 |
349 | # 进程和系统控制命令
350 |
351 | 以下是在Linux系统中管理进程和控制系统的一些常用命令:
352 |
353 | 1. ps:显示当前进程的状态
354 |
355 | ```
356 | ps aux
357 | ```
358 |
359 | 1. top:动态显示运行中的进程
360 | 2. kill:发送信号以终止进程
361 |
362 | ```
363 | kill 1234
364 | ```
365 |
366 | 1. shutdown:关闭机器
367 |
368 | ```
369 | shutdown -h now
370 | ```
371 |
372 | 1. reboot:重启机器
373 | 2. logout:退出登录会话
374 |
375 | ------
376 |
377 | # 文本操作命令
378 |
379 | 在编写或处理文本文件时,下列命令可以帮助你完成各种复杂任务:
380 |
381 | 1. echo:打印信息到终端。
382 |
383 | ```
384 | echo "Hello, World!"
385 | ```
386 |
387 | 1. printf:格式化并打印信息。
388 |
389 | ```
390 | printf "Name: %s\nAge: %d\n" "Alice" 20
391 | ```
392 |
393 | 1. sed:流编辑器,用于对文本文件进行特定的行处理和替换。
394 |
395 | ```
396 | echo "Hello, World!" | sed 's/World/Shell/g'
397 | ```
398 |
399 | 1. awk:在文本文件中进行模式扫描和处理语言。
400 |
401 | ```
402 | echo -e "name\tage\nAlice\t20\nBob\t22" | awk '{if ($2 >= 21) print $1}'
403 | ```
404 |
405 | ------
406 |
407 | # 压缩与解压命令
408 |
409 | 以下命令主要用于管理和操作文件压缩及解压:
410 |
411 | 1. tar:创建、展开及管理tar包。
412 |
413 | ```
414 | tar -cvf archive.tar folder
415 | ```
416 |
417 | 1. gzip:用于文件压缩或解压。
418 |
419 | ```
420 | gzip file
421 | ```
422 |
423 | 1. gunzip:用于解压gzip压缩的文件。
424 |
425 | ```
426 | gunzip file.gz
427 | ```
428 |
429 | 1. zip/unzip:创建和解压zip格式的压缩包。
430 |
431 | ```
432 | zip -r archive.zip folder
433 | unzip archive.zip
434 | ```
435 |
436 | ------
437 |
438 | # 磁盘使用管理命令
439 |
440 | 管理和查看磁盘使用情况:
441 |
442 | 1. df:报告文件系统磁盘空间使用情况。
443 |
444 | ```
445 | df -h
446 | ```
447 |
448 | 1. du:估计并报告文件及文件夹的磁盘使用情况。
449 |
450 | ```
451 | du -sh folder
452 | ```
453 |
454 | 1. fdisk:对磁盘进行分区管理。
455 |
456 | ```
457 | sudo fdisk -l
458 | ```
459 |
460 | 1. hdparm:查看或修改SATA/ATA磁盘参数。
461 |
462 | ```
463 | sudo hdparm -i /dev/sda
464 | ```
465 |
466 | ------
467 |
468 | # 包管理命令
469 |
470 | 在Debian,Ubuntu及其他基于Debian的系统中,可以使用以下命令进行软件包管理:
471 |
472 | 1. apt-get:APT包处理工具,用于处理包。
473 |
474 | ```
475 | sudo apt-get install package
476 | ```
477 |
478 | 1. dpkg:Debian包管理器。
479 |
480 | ```
481 | sudo dpkg -i package.deb
482 | ```
483 |
484 | 在RedHat, CentOS及其他基于RPM的系统中,可以使用以下命令进行软件包管理:
485 |
486 | 1. yum:高级软件包管理器,用于处理rpm包。
487 |
488 | ```
489 | sudo yum install package
490 | ```
491 |
492 | 1. rpm:RPM包管理器。
493 |
494 | ```
495 | sudo rpm -i package.rpm
496 | ```
497 |
498 | ------
499 |
500 | # 进程管理命令
501 |
502 | 查看和管理正在运行的进程:
503 |
504 | 1. ps:报告进程当前状态。
505 |
506 | ```
507 | ps aux
508 | USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
509 | root 1 0.0 0.4 225848 7836 ? Ss Nov10 4:05 /lib/systemd/systemd --system --deserialize 39
510 | root 2 0.0 0.0 0 0 ? S Nov10 0:00 [kthreadd]
511 | root 4 0.0 0.0 0 0 ? I< Nov10 0:00 [kworker/0:0H]
512 | ```
513 |
514 | 1. top:动态显示当前耗费系统资源最多的进程。
515 | 2. htop:比top更友好的动态进程查看工具。
516 |
517 | ```
518 | htop
519 | ```
520 |
521 | 1. kill:终止或者发送一个信号到指定进程。
522 | 2. pkill:条件地终止或者发送一个信号到指定进程。
523 |
524 | ```
525 | pkill process_name
526 | ```
527 |
528 | ------
529 |
530 | # 环境变量命令
531 |
532 | 查看或设置环境变量:
533 |
534 | 1. env:显示当前所有的环境变量。
535 |
536 | ```
537 | 输入:env
538 | 输出:
539 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
540 | SHELL=/bin/bash
541 | PWD=/home/user
542 | ```
543 |
544 | 1. set:显示当前shell所有的环境变量及函数。
545 |
546 | ```
547 | 输入:set
548 | 输出:展示所环境变量以及函数
549 | ```
550 |
551 | 1. export:设置或显示环境变量。
552 |
553 | ```
554 | 输入:
555 | export VARName="Value"
556 | echo $VARName
557 | 输出结果:
558 | Value
559 | ```
560 |
561 | ------
562 |
563 | # 系统信息发布相关命令
564 |
565 | 有时,你可能想要查看有关你的系统或硬件的信息。以下命令可以帮助你做到这一点:
566 |
567 | 1. uname:会打印操作系统的名称。
568 |
569 | ```
570 | 输入:
571 | uname
572 | 输出:
573 | Linux
574 | ```
575 |
576 | 1. hostname:打印系统的主机名。
577 |
578 | ```
579 | 输入:
580 | hostname
581 | 输出:
582 | myhostname
583 | ```
584 |
585 | 1. dmesg:打印或控制内核环形缓冲区。
586 |
587 | ```
588 | 输入:
589 | dmesg | less
590 | ```
591 |
592 | 1. df:展示文件系统的磁盘空间使用情况。
593 |
594 | ```
595 | 输入:df -h
596 | 输出:
597 | Filesystem Size Used Avail Use% Mounted on
598 | udev 962M 0 962M 0% /dev
599 | tmpfs 200M 4.3M 196M 3% /run
600 | /dev/sda1 30G 4.7G 24G 17% /
601 | ```
602 |
603 | 1. free:展示系统中未使用和已经使用的物理和swap内存。
604 |
605 | ```
606 | 输入:free -h
607 | 输出:
608 | total used free shared buff/cache available
609 | Mem: 3.8G 487M 1.9G 122M 1.4G 3.0G
610 | Swap: 0B 0B 0B
611 | ```
612 |
613 | 1. uptime:展示系统已经运行了多久,有多少用户正在登录,以及系统负载。
614 |
615 | ```
616 | 输入:uptime
617 | 输出: 16:14:30 up 43 min, 1 user, load average: 0.34, 0.36, 0.40
618 | ```
619 |
620 | 1. last:查看系统的重启和关机记录。
621 |
622 | ```
623 | 输入:last reboot
624 | ```
625 |
626 | 1. w:展示哪些用户正在登录。
627 |
628 | ```
629 | 输入:w
630 | 输出: 16:17:51 up 1:42, 1 user, load average: 0.45, 0.47, 0.38
631 | USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
632 | user tty1 14:36 1:42m 1.55s 0.06s w
633 | ```
634 |
635 | 1. who:展示哪些用户正在登录,和w命令相似但信息更少。
636 |
637 | ```
638 | 输入:who
639 | 输出: user tty1 2022-01-28 14:36
640 | ```
641 |
642 | 1. id:展示当前用户的UID、GID以及所在的组。
643 |
644 | ```
645 | 输入:id
646 | 输出:uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare)
647 | ```
648 |
649 | ------
650 |
651 | # 系统控制命令
652 |
653 | 在一些特殊情况下,你可能需要进行一些系统控制操作。以下命令可以帮助你做到这一点:
654 |
655 | 1. halt:关机。
656 |
657 | ```
658 | 输入:sudo halt
659 | ```
660 |
661 | 1. reboot:重启系统。
662 |
663 | ```
664 | 输入:sudo reboot
665 | ```
666 |
667 | 1. shutdown:关机或者重启,和上述两个命令一样,但是提供更多的选项。
668 |
669 | ```
670 | 关闭系统:sudo shutdown -h now
671 | 重启系统:sudo shutdown -r now
672 | ```
673 |
674 | 1. passwd:更改用户密码。
675 |
676 | ```
677 | 更改密码:passwd
678 | ```
679 |
680 | ------
681 |
682 | # 文本编辑器命令
683 |
684 | Linux提供了多种命令行文本编辑器。以下这些可能是你需要知道的:
685 |
686 | 1. vi/vim:vi是一个文本编辑器,而vim是vi的改进版,提供了更多的功能。
687 | 2. nano:一个简单易用的命令行文本编辑器。
688 | 3. emac:一个强大的文本编辑器,也是一个定制化的计算环境。
689 |
690 | # 其他常用命令
691 |
692 | 1. man:查看命令的帮助文档。
693 | 2. whatis:显示一个命令的简单描述。
694 |
695 | ```
696 | 输入:whatis ls
697 | 输出:ls (1) - list directory contents
698 | ```
699 |
700 | 1. whereis:查找命令的二进制文件、源文件及帮助文档位置。
701 |
702 | ```
703 | 输入:whereis ls
704 | 输出:ls: /bin/ls /usr/share/man/man1/ls.1.gz
705 | ```
706 |
707 | 1. which:查找并显示给定命令的完整路径。
708 |
709 | ```
710 | 输入:which ls
711 | 输出:/bin/ls
712 | ```
713 |
714 | 1. whoami:打印当前有效的用户名。
715 |
716 | ```
717 | 输入:whoami
718 | 输出:user
719 | ```
720 |
721 | 1. date:显示或设置系统日期和时间
722 |
723 | ```
724 | 输入:date
725 | 输出: Tue Dec 21 02:16:12 UTC 2021
726 | ```
727 |
728 | 1. cal:显示日历
729 |
730 | ```
731 | 输入:cal
732 | 输出:
733 | January 2022
734 | Su Mo Tu We Th Fr Sa
735 | 1
736 | 2 3 4 5 6 7 8
737 | 9 10 11 12 13 14 15
738 | 16 17 18 19 20 21 22
739 | 23 24 25 26 27 28 29
740 | 30 31
741 | ```
742 |
743 | 1. alias:创建命令别名
744 | 2. unalias:删除别名
745 | 3. history:显示命令历史
746 | 4. clear:清除屏幕或窗口内容
747 | 5. watch:用于实时查看当前命令打印信息
748 |
749 | ```
750 | 输入:watch -n 2 date
751 | 解释:watch`命令会每2秒运行一次`date`命令,并实时显示输出
752 | ```
753 |
754 | 大多数人学习Shell脚本的最大动力是提高效率。使用Shell脚本,你可以编写一个任务,然后让计算机去做,而你可以去忙其他的事情;你可以编写一个任务,让计算机重复执行,而不需要你每次在命令行手动输入;你可以更灵活地处理任务,比如管理用户,管理程序等。就这样,Shell脚本赋予你控制计算机的能力,在你的指尖下,一切尽在掌握。
755 |
756 | 在未来,实践未知,探索无限,最好的方式是动手试试看,愿这完整的100个命令清单能够成为你在Linux世界里的指南针!掌握Shell命令并利用它们来编写脚本能够极大地提升你的工作效率,无论是进行系统管理还是进行程序设计,这都是一种强大的工具。善用它,享受编程带给你的乐趣吧!
757 |
758 |
759 |
760 | 原文地址:https://mp.weixin.qq.com/s/5rnAe-qNZNlxRsEnfSlqMg
761 |
--------------------------------------------------------------------------------
/Linux系统入门系列之一.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://cloud.tencent.com/developer/article/1991217
2 |
3 |
4 |
5 | # Linux系统入门系列之一
6 |
7 |
8 |
9 | 在生物信息分析中,通常要借助于大型服务器来处理各种数据,而Linux系统是比较通用的服务器操作系统,因此Linux系统的学习十分重要,熟识Linux命令与Shell脚本能帮助我们高效的完成生信分析任务。
10 |
11 |
12 |
13 | 在Linux系统中,我们一般通过命令行指令来执行各种任务。无论是个人PC版Linux系统,还是远程[服务器](https://cloud.tencent.com/product/cvm/?from_column=20065&from=20065),我们一般通过图形界面X Window软件与计算机进行交互。个人PC版Linux系统自带图形界面,可以打开终端(terminal)输入指令;对于远程服务器,我们则需要模拟终端软件的帮助,最常用的为Xshell,其界面如下所示:
14 |
15 | 
16 |
17 | 执行“文件”→“新建”,在“主机”一栏输入服务器IP,选择相应端口,就可以建立一个自己电脑与远程服务器的连接,如下所示:
18 |
19 | 
20 |
21 | 点击“确定”之后就会出现登录界面,输入管理员分配的账号密码即可。除了Xshell之外,Xftp是一个很好的服务器与电脑文件传输管理工具,如下所示:
22 |
23 | 
24 |
25 | 点击“新建”就可以创建一个与服务器的连接,在Xshell中有开启Xftp的快捷方式Ctrl+Alt+F,如下所示:
26 |
27 | 
28 |
29 | **在Xshell的命令行输入相应的命令(多个命令以分号“;”隔开)以及参数并按回车键Enter执行,就可以使用服务器完成各种任务。**
30 |
31 | 1
32 |
33 | **基础操作**
34 |
35 | ##### 1.1时间与日期
36 |
37 | 命令:date
38 |
39 | 显示日期,示例如下:
40 |
41 | 
42 |
43 | 显示年月日:
44 |
45 | 
46 |
47 | 显示时分:
48 |
49 | 
50 |
51 | 显示时分秒:
52 |
53 | 
54 |
55 | 命令:cal
56 |
57 | 列出当前月份的日历,示例如下:
58 |
59 | 
60 |
61 | 列出指定年月的日历:
62 |
63 | 
64 |
65 | 通过两个基础命令的练习,希望学习者可以初步感受什么是指令操作。
66 |
67 | ##### 1.2基础工具
68 |
69 | 命令:bc
70 |
71 | 基础运算工具,示例如下:
72 |
73 | 
74 |
75 | 其中%为求余数,quit为退出。bc默认输出整数,要输出小数,可以使用scale参数,示例如下:
76 |
77 | 
78 |
79 | 命令:nano
80 |
81 | 简单好用的书写记录软件,示例如下:
82 |
83 | 
84 |
85 | 通过“Ctrl+□”快捷键来控制保存(Ctrl+O)、退出(Ctrl+X)等:
86 |
87 | 
88 |
89 | 命令:echo
90 |
91 | echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号。在屏幕显示字符串,示例如下:
92 |
93 | 
94 |
95 | 在文件中写入字符串(>为覆盖原来的内容,>>为追加到文件后面):
96 |
97 | 
98 |
99 | 显示目前所支持的语言:
100 |
101 | 
102 |
103 | 修改语言为中文并输出中文字符:
104 |
105 | 
106 |
107 | 如果想要在双引号内使用反斜杠转义字符,需添加-e参数。
108 |
109 | 命令:man
110 |
111 | 查询Linux内置的帮助文件,了解命令的使用方法,例如输入“man date”回车,就可显示命令date的帮助文档,如下所示:
112 |
113 | 
114 |
115 | 
116 |
117 | 通过以上练习,希望学习者可以初步感受Linux中软件的调用方式。
118 |
119 | ##### 1.3.快捷热键
120 |
121 | 热键:Tab
122 |
123 | 命令补全,若没有记全一个命令,可以只输入已知部分,紧接着按两次Tab,系统便会显示所有相关的命令,示例如下:
124 |
125 | 
126 |
127 | 文件补全:
128 |
129 | 
130 |
131 | 对于非隐藏文件,输入部分文件名紧接着按一次tab,就会自动输入后续部分,如ls-al ~/prac[Tab]tice.[Tab]txt:
132 |
133 | 
134 |
135 | 热键:Ctrl+C
136 |
137 | 停止一个错误的命令或者退出一个输错的命令,示例如下:
138 |
139 | 
140 |
141 | 热键:\+Enter
142 |
143 | 一般情况下Enter表示的是命令执行,反斜杠转义为换行,示例如下:
144 |
145 | 
146 |
147 | 2
148 |
149 | **文件管理**
150 |
151 | ##### 2.1文件查看
152 |
153 | 命令:ls
154 |
155 | 添加参数-al列出当前路径下所有文件,示例如下:
156 |
157 | 
158 |
159 | 添加参数-l列出非隐藏文件:
160 |
161 | 
162 |
163 | 或者简写为ll:
164 |
165 | 
166 |
167 | 其中“-”后面为参数选项[Option],对ls(或ll)命令常用选项如下:
168 |
169 | -a:全部的文件,连同隐藏文件(开头为“.”的文件)一起列出来;
170 |
171 | -d:仅列出目录本身,而不是列出目录内的文件数据;
172 |
173 | -l:长数据串列出,包含文件的属性与权限等等数据;
174 |
175 | -R:若列出对象为路径且目录下有文件,则将所有文件依序列出;
176 |
177 | -t:按照最后修改时间顺序列出文件,由旧到新;
178 |
179 | -h:文件大小显示单位(K、M、G等)。
180 |
181 | 命令:tree
182 |
183 | 将某路径下文件夹及文件以树状图展示,当前路径下使用示例如下:
184 |
185 | 
186 |
187 | 命令tree的参数选项如下:
188 |
189 | -d:只显示目录;
190 |
191 | -D:列出文件或目录的更改时间;
192 |
193 | -f:在每个文件或目录之前,显示完整的相对路径名称;
194 |
195 | -L:后接数字,显示到第几级子目录;
196 |
197 | -s:列出文件或目录大小;
198 |
199 | -t:用文件和目录的更改时间排序。
200 |
201 | 命令:find
202 |
203 | 查找只知道部分名字的某文件及其路径,全盘搜索示例如下:
204 |
205 | 
206 |
207 | 只在当前目录下搜索:
208 |
209 | 
210 |
211 | 此命令常用到通配符来进行模糊查找,常用通配符如下:
212 |
213 | | 符号 | 意义 |
214 | | :--- | :----------------------------------------------------------- |
215 | | * | 表示0个到无穷多个任意字符。例如a*可以表示a,ab,abc,... |
216 | | ? | 表示1个任意字符。例如a?可以表示ab,ac,但是不能表示a或者abc |
217 | | [] | 表示一个在中括号中的字符。例如[abc]表示a,b,c中的一个 |
218 | | [-] | 表示在编码顺序内的所有字符。例如[a-z]表示字母a到z;[0-9]表示数字0到9 |
219 | | [^] | 反向选择,表示在中括号中以外的一个字符。例如[^abc]表示字母a,b,c以外的其他字符 |
220 |
221 | 命令:locate
222 |
223 | 使用locate搜索linux系统中的文件,它比find命令速度快很多,因为它查询的是[数据库](https://cloud.tencent.com/product/tencentdb-catalog?from_column=20065&from=20065)(/var/lib/locatedb),数据库包含本地所有的文件信息。使用locate加文件名便可在根目录下搜索相应文件,如下所示:
224 |
225 | 
226 |
227 | 命令:cat
228 |
229 | 在屏幕上显示文件内容,示例如下:
230 |
231 | 
232 |
233 | 将两个文本文件整合为一个文本文件(行累加),示例如下:
234 |
235 | 
236 |
237 | 添加参数-A查看文本文档的格式(显示tab空格等所有特殊键):
238 |
239 | 
240 |
241 | 其中^I即为tab键。具体参数选项如下:
242 |
243 | -A:相当于-vET的整合选项,可列出一些特殊字符而不是空格显示;
244 |
245 | -b:列出行号,仅针对非空白行做行号显示,空白行不标行号;
246 |
247 | -n:列印出行号,连同空白行也会有行号,与-b的选项不同;
248 |
249 | -E:将结尾的断行字节$显示出来;
250 |
251 | -T:将[tab]按键以^I显示出来;
252 |
253 | -v:列出一些看不出来的特殊字符。
254 |
255 | 命令:nl
256 |
257 | 列出文本内容并打印行号,示例如下:
258 |
259 | 
260 |
261 | 命令:head
262 |
263 | 显示文件前面部分,例如显示前三行:
264 |
265 | 
266 |
267 | 此外还有命令tail,从尾行提取特定行数,这两个命令搭配管道命令可选取文件特定的行数范围进行显示。
268 |
269 | 命令:less
270 |
271 | 对于大的文本文档cat查看比较困难,而less可以进行分页查看,示例如下:
272 |
273 | 
274 |
275 | 按键F向下翻页,B向上翻页,空格向下翻页,Enter滚动一行,Q退出less命令:
276 |
277 | 
278 |
279 | 若要横向超出屏幕部分不强制换行展示,可添加-S参数:
280 |
281 | 
282 |
283 | 若要查找内容使用/+内容(或?+内容向上搜索)然后回车即可,如下所示:
284 |
285 | 
286 |
287 | 
288 |
289 | 此查找支持正则表达式。
290 |
291 | 2.2文件路径
292 |
293 | 命令:ln
294 |
295 | 在当前路径下创建某文件的超链接,示例如下:
296 |
297 | 
298 |
299 | 命令:cd
300 |
301 | 去往一个路径(路径切换),其中cd空格或者cd~表示返回用户主目录,cd ..表示返回上一级目录(返回上两级则是cd ../..表示返回上两级)示例如下:
302 |
303 | 
304 |
305 | 命令:mkdir
306 |
307 | 在当前路径下新建路径(文件夹),示例如下:
308 |
309 | 
310 |
311 | 此命令具有以下选项:
312 |
313 | -m:配置文件的权限;
314 |
315 | -p:创建递归目录。
316 |
317 | 命令:rmdir
318 |
319 | 删除当前路径下的路径(文件夹),示例如下:
320 |
321 | 
322 |
323 | 命令:rm
324 |
325 | 删除当前路径下文件或路径(多个文件空格隔开),示例如下:
326 |
327 | 
328 |
329 | 添加参数-r可删除路径以及所含有的文件:
330 |
331 | 
332 |
333 | 命令:cp
334 |
335 | 复制文件或目录到一个新的目录,示例如下
336 |
337 | 
338 |
339 | 复制多个文件,空格隔开,只要最后一个是目的路径即可:
340 |
341 | 
342 |
343 | 若是复制到当前文件夹,目的路径为“.”:
344 |
345 | 
346 |
347 | 将某路径下所有文件复制到一个新的文件夹:
348 |
349 | 
350 |
351 | 此命令具有以下常用选项:
352 |
353 | -a:相当于-pdr;
354 |
355 | -d:若source为链接文件(linkfile),则复制链接属性而非文件本身;
356 |
357 | -f:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;
358 |
359 | -i:若目标文件(destination)已经存在时,在覆盖时会先进行询问(常用);
360 |
361 | -p:连同文件的属性一起复制过去,而非使用默认属性;
362 |
363 | -r:递归持续复制,用于目录的复制行为。
364 |
365 | 命令:mv
366 |
367 | 移动当前路径下文件或目录到另一个文件夹,示例如下:
368 |
369 | 
370 |
371 | 对文件重命名:
372 |
373 | 
374 |
375 | 此命令具有以下常用选项:
376 |
377 | -f:force强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
378 |
379 | i:若目标文件(destination) 已经存在时,询问是否覆盖;
380 |
381 | -u:若目标文件已经存在,且source比较新(即最后修改时间比较晚),才会覆盖(修改时间比较早的旧文件)。
382 |
383 | 命令:touch
384 |
385 | 创建新的文件(不是文件夹),示例如下:
386 |
387 | 
388 |
389 | 命令:du
390 |
391 | 查看文件或文件夹磁盘占用空间大小,如下所示:
392 |
393 | 
394 |
395 | 其参数选项如下所示:
396 |
397 | -a:列出所有的文件与目录大小,因为默认仅列出路径
398 |
399 | -h:以人们较易读的容量格式(G/M)显示;
400 |
401 | -s:列出总量,而不列出每个各别的目录占用空间;
402 |
403 | -S:不包括子目录下的总计,与-s有点差别。
404 |
405 | -k:以KBytes列出容量显示;
406 |
407 | -m:以MBytes列出容量显示。
408 |
409 | 命令:rz
410 |
411 | 从电脑传输文件到服务器,示例如下:
412 |
413 | 
414 |
415 | 命令:sz
416 |
417 | 从服务器传输文件到电脑,示例如下:
418 |
419 | 
420 |
421 | 以上两个命令需要电脑预先安装Xftp。
422 |
423 | ##### 2.3文件压缩
424 |
425 | 命令:gzip, zcat
426 |
427 | 使用gzip压缩、读取、解压文件,示例如下:
428 |
429 | 
430 |
431 | 命令:bzip2, bzcat, zip, unzip
432 |
433 | 使用bzip2压缩,用法与gzip类似。
434 |
435 | 命令:tar
436 |
437 | 打包并压缩文件或目录,示例如下:
438 |
439 | 
440 |
441 | 解压打包文件:
442 |
443 | 
444 |
445 | 命令:file
446 |
447 | 在Linux系统中有时候文件名后缀不能完全显示文件格式,使用file命令可查看文件格式,是否被压缩以及使用什么软件压缩,示例如下:
448 |
449 | 
450 |
451 | 可以看出这时候文件虽然没有“.gz”的后缀,但是是gzip压缩文件,这时候不能直接解压,需要添加后缀并解压:
452 |
453 | 
454 |
455 | ##### 2.4文件下载
456 |
457 | 命令:wget
458 |
459 | wget是linux最常用的下载命令,可以从网络上自动下载文件,它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理。所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行。其使用方法如下:
460 |
461 | wget[Options] 要下载文件的网址(包含文件名)
462 |
463 | 其中Options:
464 |
465 | -A:指定要下载文件的后缀名,多个后缀名之间使用逗号进行分隔
466 |
467 | -c:断点续传,继续执行上次的下载命令
468 |
469 | -b:启动后转入后台执行
470 |
471 | -i:从指定文件获取要下载的URL地址,文件中每行指定一个网址
472 |
473 | -O:指定下载后的文件路径及保存为的文件名
474 |
475 | 具体下载方法如下所示:
476 |
477 | 
478 |
479 | 其中文件名支持使用通配符而进行批量下载。
480 |
481 | ##### 2.5文件权限
482 |
483 | 在查看文件的时候,最前面的信息即为文件权限,示例如下:
484 |
485 | 
486 |
487 | 一共有10位,第一位d代表路径(文件夹),-代表文件,之后每三位一组分别为文件所有者、用户组、其他人的权限,r为可读,w为可写,x为可执行,-为无权限。
488 |
489 | 命令:chmod
490 |
491 | 更改文件或路径的权限,示例如下:
492 |
493 | 
494 |
495 | 其中r:4,w2,x1。更改目录及其下属文件的权限:
496 |
497 | 
498 |
499 |
--------------------------------------------------------------------------------
/Linux02:常用的基本命令.md:
--------------------------------------------------------------------------------
1 | 原文链接:https://mp.weixin.qq.com/s/4dZ3mbu287pC6mdGOczGAA
2 |
3 |
4 |
5 | # Linux02:常用的基本命令(必掌握)
6 |
7 |
8 |
9 | 常用的基本命令
10 |
11 | ### 目录管理
12 |
13 | > 绝对路径和相对路径
14 |
15 | 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。
16 |
17 | 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们。
18 |
19 | 在开始本教程前我们需要先知道什么是绝对路径与相对路径。
20 |
21 | **绝对路径:**
22 |
23 | 路径的写法,由根目录 / 写起,例如:/usr/share/doc 这个目录。
24 |
25 | **相对路径:**
26 |
27 | 路径的写法,不是由 / 写起,例如由 /usr/share/doc 要到 /usr/share/man 底下时,可以写成:cd ../man 这就是相对路径的写法啦!
28 |
29 | > 处理目录的常用命令
30 |
31 | 接下来我们就来看几个常见的处理目录的命令吧:
32 |
33 | - ls: 列出目录
34 | - cd:切换目录
35 | - pwd:显示目前的目录
36 | - mkdir:创建一个新的目录
37 | - rmdir:删除一个空的目录
38 | - cp: 复制文件或目录
39 | - rm: 移除文件或目录
40 | - mv: 移动文件与目录,或修改文件与目录的名称
41 |
42 | 你可以使用 *man [命令]* 来查看各个命令的使用文档,如 :man cp。
43 |
44 | > ls (列出目录)
45 |
46 | 在Linux系统当中, ls 命令可能是最常被运行的。
47 |
48 | 语法:
49 |
50 | ```
51 | [root@www ~]# ls [-aAdfFhilnrRSt] 目录名称
52 | ```
53 |
54 | 选项与参数:
55 |
56 | - -a :全部的文件,连同隐藏文件( 开头为 . 的文件) 一起列出来(常用)
57 | - -l :长数据串列出,包含文件的属性与权限等等数据;(常用)
58 |
59 | 将目录下的所有文件列出来(含属性与隐藏档)
60 |
61 | ```
62 | [root@www ~]# ls -al ~
63 | ```
64 |
65 | > cd (切换目录)
66 |
67 | cd是Change Directory的缩写,这是用来变换工作目录的命令。
68 |
69 | 语法:
70 |
71 | ```
72 | cd [相对路径或绝对路径]
73 | ```
74 |
75 | 测试:
76 |
77 | ```
78 | # 切换到用户目录下
79 | [root@kuangshen /]# cd home
80 |
81 | # 使用 mkdir 命令创建 kuangstudy 目录
82 | [root@kuangshen home]# mkdir kuangstudy
83 |
84 | # 进入 kuangstudy 目录
85 | [root@kuangshen home]# cd kuangstudy
86 |
87 | # 回到上一级
88 | [root@kuangshen kuangstudy]# cd ..
89 |
90 | # 回到根目录
91 | [root@kuangshen kuangstudy]# cd /
92 |
93 | # 表示回到自己的家目录,亦即是 /root 这个目录
94 | [root@kuangshen kuangstudy]# cd ~
95 | ```
96 |
97 | 接下来大家多操作几次应该就可以很好的理解 cd 命令的。
98 |
99 | > pwd ( 显示目前所在的目录 )
100 |
101 | pwd 是 **Print Working Directory** 的缩写,也就是显示目前所在目录的命令。
102 |
103 | ```
104 | [root@kuangshen kuangstudy]#pwd [-P]
105 | ```
106 |
107 | 选项与参数:**-P** :显示出确实的路径,而非使用连接(link) 路径。
108 |
109 | 测试:
110 |
111 | ```
112 | # 单纯显示出目前的工作目录
113 | [root@kuangshen ~]# pwd
114 | /root
115 |
116 | # 如果是链接,要显示真实地址,可以使用 -P参数
117 | [root@kuangshen /]# cd bin
118 | [root@kuangshen bin]# pwd -P
119 | /usr/bin
120 | ```
121 |
122 | > mkdir (创建新目录)
123 |
124 | 如果想要创建新的目录的话,那么就使用mkdir (make directory)吧。
125 |
126 | ```
127 | mkdir [-mp] 目录名称
128 | ```
129 |
130 | 选项与参数:
131 |
132 | - -m :配置文件的权限喔!直接配置,不需要看默认权限 (umask) 的脸色~
133 | - -p :帮助你直接将所需要的目录(包含上一级目录)递归创建起来!
134 |
135 | 测试:
136 |
137 | ```
138 | # 进入我们用户目录下
139 | [root@kuangshen /]# cd /home
140 |
141 | # 创建一个 test 文件夹
142 | [root@kuangshen home]# mkdir test
143 |
144 | # 创建多层级目录
145 | [root@kuangshen home]# mkdir test1/test2/test3/test4
146 | mkdir: cannot create directory ‘test1/test2/test3/test4’:
147 | No such file or directory # <== 没办法直接创建此目录啊!
148 |
149 | # 加了这个 -p 的选项,可以自行帮你创建多层目录!
150 | [root@kuangshen home]# mkdir -p test1/test2/test3/test4
151 |
152 | # 创建权限为 rwx--x--x 的目录。
153 | [root@kuangshen home]# mkdir -m 711 test2
154 | [root@kuangshen home]# ls -l
155 | drwxr-xr-x 2 root root 4096 Mar 12 21:55 test
156 | drwxr-xr-x 3 root root 4096 Mar 12 21:56 test1
157 | drwx--x--x 2 root root 4096 Mar 12 21:58 test2
158 | ```
159 |
160 | > rmdir ( 删除空的目录 )
161 |
162 | 语法:
163 |
164 | ```
165 | rmdir [-p] 目录名称
166 | ```
167 |
168 | 选项与参数:**-p :**连同上一级『空的』目录也一起删除
169 |
170 | 测试:
171 |
172 | ```
173 | # 看看有多少目录存在?
174 | [root@kuangshen home]# ls -l
175 | drwxr-xr-x 2 root root 4096 Mar 12 21:55 test
176 | drwxr-xr-x 3 root root 4096 Mar 12 21:56 test1
177 | drwx--x--x 2 root root 4096 Mar 12 21:58 test2
178 |
179 | # 可直接删除掉,没问题
180 | [root@kuangshen home]# rmdir test
181 |
182 | # 因为尚有内容,所以无法删除!
183 | [root@kuangshen home]# rmdir test1
184 | rmdir: failed to remove ‘test1’: Directory not empty
185 |
186 | # 利用 -p 这个选项,立刻就可以将 test1/test2/test3/test4 依次删除。
187 | [root@kuangshen home]# rmdir -p test1/test2/test3/test4
188 | ```
189 |
190 | 注意:这个 rmdir 仅能删除空的目录,你可以使用 rm 命令来删除非空目录,后面我们会将!
191 |
192 | > cp ( 复制文件或目录 )
193 |
194 | 语法:
195 |
196 | ```
197 | [root@www ~]# cp [-adfilprsu] 来源档(source) 目标档(destination)
198 | [root@www ~]# cp [options] source1 source2 source3 .... directory
199 | ```
200 |
201 | 选项与参数:
202 |
203 | - **-a:**相当於 -pdr 的意思,至於 pdr 请参考下列说明;(常用)
204 | - **-p:**连同文件的属性一起复制过去,而非使用默认属性(备份常用);
205 | - **-d:**若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;
206 | - **-r:**递归持续复制,用於目录的复制行为;(常用)
207 | - **-f:**为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;
208 | - **-i:**若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
209 | - **-l:**进行硬式连结(hard link)的连结档创建,而非复制文件本身。
210 | - **-s:**复制成为符号连结档 (symbolic link),亦即『捷径』文件;
211 | - **-u:**若 destination 比 source 旧才升级 destination !
212 |
213 | 测试:
214 |
215 | ```
216 | # 找一个有文件的目录,我这里找到 root目录
217 | [root@kuangshen home]# cd /root
218 | [root@kuangshen ~]# ls
219 | install.sh
220 | [root@kuangshen ~]# cd /home
221 |
222 | # 复制 root目录下的install.sh 到 home目录下
223 | [root@kuangshen home]# cp /root/install.sh /home
224 | [root@kuangshen home]# ls
225 | install.sh
226 |
227 | # 再次复制,加上-i参数,增加覆盖询问?
228 | [root@kuangshen home]# cp -i /root/install.sh /home
229 | cp: overwrite ‘/home/install.sh’? y # n不覆盖,y为覆盖
230 | ```
231 |
232 | > rm ( 移除文件或目录 )
233 |
234 | 语法:
235 |
236 | ```
237 | rm [-fir] 文件或目录
238 | ```
239 |
240 | 选项与参数:
241 |
242 | - -f :就是 force 的意思,忽略不存在的文件,不会出现警告信息;
243 | - -i :互动模式,在删除前会询问使用者是否动作
244 | - -r :递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!
245 |
246 | 测试:
247 |
248 | ```
249 | # 将刚刚在 cp 的实例中创建的 install.sh删除掉!
250 | [root@kuangshen home]# rm -i install.sh
251 | rm: remove regular file ‘install.sh’? y
252 | # 如果加上 -i 的选项就会主动询问喔,避免你删除到错误的档名!
253 |
254 | # 尽量不要在服务器上使用 rm -rf /
255 | ```
256 |
257 | > mv ( 移动文件与目录,或修改名称 )
258 |
259 | 语法:
260 |
261 | ```
262 | [root@www ~]# mv [-fiu] source destination
263 | [root@www ~]# mv [options] source1 source2 source3 .... directory
264 | ```
265 |
266 | 选项与参数:
267 |
268 | - -f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
269 | - -i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
270 | - -u :若目标文件已经存在,且 source 比较新,才会升级 (update)
271 |
272 | 测试:
273 |
274 | ```
275 | # 复制一个文件到当前目录
276 | [root@kuangshen home]# cp /root/install.sh /home
277 |
278 | # 创建一个文件夹 test
279 | [root@kuangshen home]# mkdir test
280 |
281 | # 将复制过来的文件移动到我们创建的目录,并查看
282 | [root@kuangshen home]# mv install.sh test
283 | [root@kuangshen home]# ls
284 | test
285 | [root@kuangshen home]# cd test
286 | [root@kuangshen test]# ls
287 | install.sh
288 |
289 | # 将文件夹重命名,然后再次查看!
290 | [root@kuangshen test]# cd ..
291 | [root@kuangshen home]# mv test mvtest
292 | [root@kuangshen home]# ls
293 | mvtest
294 | ```
295 |
296 | ### 基本属性
297 |
298 | > 看懂文件属性
299 |
300 | Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。
301 |
302 | 在Linux中我们可以使用`ll`或者`ls –l`命令来显示一个文件的属性以及文件所属的用户和组,如:
303 |
304 | 
305 |
306 | 实例中,boot文件的第一个属性用"d"表示。"d"在Linux中代表该文件是一个目录文件。
307 |
308 | 在Linux中第一个字符代表这个文件是目录、文件或链接文件等等:
309 |
310 | - 当为[ **d** ]则是目录
311 | - 当为[ **-** ]则是文件;
312 | - 若是[ **l** ]则表示为链接文档 ( link file );
313 | - 若是[ **b** ]则表示为装置文件里面的可供储存的接口设备 ( 可随机存取装置 );
314 | - 若是[ **c** ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标 ( 一次性读取装置 )。
315 |
316 | 接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。
317 |
318 | 其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。
319 |
320 | 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。
321 |
322 | 每个文件的属性由左边第一部分的10个字符来确定(如下图):
323 |
324 | 
325 |
326 | 从左至右用0-9这些数字来表示。
327 |
328 | 第0位确定文件类型,第1-3位确定属主(该文件的所有者)拥有该文件的权限。第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。
329 |
330 | 其中:
331 |
332 | 第1、4、7位表示读权限,如果用"r"字符表示,则有读权限,如果用"-"字符表示,则没有读权限;
333 |
334 | 第2、5、8位表示写权限,如果用"w"字符表示,则有写权限,如果用"-"字符表示没有写权限;
335 |
336 | 第3、6、9位表示可执行权限,如果用"x"字符表示,则有执行权限,如果用"-"字符表示,则没有执行权限。
337 |
338 | 对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。
339 |
340 | 同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。
341 |
342 | 文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。
343 |
344 | 因此,Linux系统按文件所有者、文件所有者同组用户和其他用户来规定了不同的文件访问权限。
345 |
346 | 在以上实例中,boot 文件是一个目录文件,属主和属组都为 root。
347 |
348 |
349 |
350 | > 修改文件属性
351 |
352 | **1、chgrp:更改文件属组**
353 |
354 | ```
355 | chgrp [-R] 属组名 文件名
356 | ```
357 |
358 | -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。
359 |
360 | **2、chown:更改文件属主,也可以同时更改文件属组**
361 |
362 | ```
363 | chown [–R] 属主名 文件名
364 | chown [-R] 属主名:属组名 文件名
365 | ```
366 |
367 | **3、chmod:更改文件9个属性**
368 |
369 | ```
370 | chmod [-R] xyz 文件或目录
371 | ```
372 |
373 | Linux文件属性有两种设置方法,一种是数字,一种是符号。
374 |
375 | Linux文件的基本权限就有九个,分别是owner/group/others三种身份各有自己的read/write/execute权限。
376 |
377 | 先复习一下刚刚上面提到的数据:文件的权限字符为:『-rwxrwxrwx』, 这九个权限是三个三个一组的!其中,我们可以使用数字来代表各个权限,各权限的分数对照表如下:
378 |
379 | ```
380 | r:4 w:2 x:1
381 | ```
382 |
383 | 每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为:[-rwxrwx---] 分数则是:
384 |
385 | - owner = rwx = 4+2+1 = 7
386 | - group = rwx = 4+2+1 = 7
387 | - others= --- = 0+0+0 = 0
388 |
389 | ```
390 | chmod 770 filename
391 | ```
392 |
393 | 可以自己下去多进行测试!
394 |
395 |
396 |
397 | ### 文件内容查看
398 |
399 | > 概述
400 |
401 | Linux系统中使用以下命令来查看文件的内容:
402 |
403 | - cat 由第一行开始显示文件内容
404 | - tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
405 | - nl 显示的时候,顺道输出行号!
406 | - more 一页一页的显示文件内容
407 | - less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
408 | - head 只看头几行
409 | - tail 只看尾巴几行
410 |
411 | 你可以使用 *man [命令]*来查看各个命令的使用文档,如 :man cp。
412 |
413 | > cat 由第一行开始显示文件内容
414 |
415 | 语法:
416 |
417 | ```
418 | cat [-AbEnTv]
419 | ```
420 |
421 | 选项与参数:
422 |
423 | - -A :相当於 -vET 的整合选项,可列出一些特殊字符而不是空白而已;
424 | - -b :列出行号,仅针对非空白行做行号显示,空白行不标行号!
425 | - -E :将结尾的断行字节 $ 显示出来;
426 | - -n :列印出行号,连同空白行也会有行号,与 -b 的选项不同;
427 | - -T :将 [tab] 按键以 ^I 显示出来;
428 | - -v :列出一些看不出来的特殊字符
429 |
430 | 测试:
431 |
432 | ```
433 | # 查看网络配置: 文件地址 /etc/sysconfig/network-scripts/
434 | [root@kuangshen ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
435 | DEVICE=eth0
436 | BOOTPROTO=dhcp
437 | ONBOOT=yes
438 | ```
439 |
440 | > tac
441 |
442 | tac与cat命令刚好相反,文件内容从最后一行开始显示,可以看出 tac 是 cat 的倒着写!如:
443 |
444 | ```
445 | [root@kuangshen ~]# tac /etc/sysconfig/network-scripts/ifcfg-eth0
446 | ONBOOT=yes
447 | BOOTPROTO=dhcp
448 | DEVICE=eth0
449 | ```
450 |
451 |
452 |
453 | > nl 显示行号
454 |
455 | 语法:
456 |
457 | ```
458 | nl [-bnw] 文件
459 | ```
460 |
461 | 选项与参数:
462 |
463 | - -b :指定行号指定的方式,主要有两种:-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);-b t :如果有空行,空的那一行不要列出行号(默认值);
464 | - -n :列出行号表示的方法,主要有三种:-n ln :行号在荧幕的最左方显示;-n rn :行号在自己栏位的最右方显示,且不加 0 ;-n rz :行号在自己栏位的最右方显示,且加 0 ;
465 | - -w :行号栏位的占用的位数。
466 |
467 | 测试:
468 |
469 | ```
470 | [root@kuangshen ~]# nl /etc/sysconfig/network-scripts/ifcfg-eth0
471 | 1DEVICE=eth0
472 | 2BOOTPROTO=dhcp
473 | 3ONBOOT=yes
474 | ```
475 |
476 |
477 |
478 | > more 一页一页翻动
479 |
480 | 在 more 这个程序的运行过程中,你有几个按键可以按的:
481 |
482 | - 空白键 (space):代表向下翻一页;
483 | - Enter :代表向下翻『一行』;
484 | - /字串 :代表在这个显示的内容当中,向下搜寻『字串』这个关键字;
485 | - :f :立刻显示出档名以及目前显示的行数;
486 | - q :代表立刻离开 more ,不再显示该文件内容。
487 | - b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管线无用。
488 |
489 | ```
490 | [root@kuangshen etc]# more /etc/csh.login
491 | ....(中间省略)....
492 | --More--(28%) # 重点在这一行喔!你的光标也会在这里等待你的命令
493 | ```
494 |
495 |
496 |
497 | > less 一页一页翻动,以下实例输出/etc/man.config文件的内容:
498 |
499 | less运行时可以输入的命令有:
500 |
501 | - 空白键 :向下翻动一页;
502 | - [pagedown]:向下翻动一页;
503 | - [pageup] :向上翻动一页;
504 | - /字串 :向下搜寻『字串』的功能;
505 | - ?字串 :向上搜寻『字串』的功能;
506 | - n :重复前一个搜寻 (与 / 或 ? 有关!)
507 | - N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
508 | - q :离开 less 这个程序;
509 |
510 | ```
511 | [root@kuangshen etc]# more /etc/csh.login
512 | ....(中间省略)....
513 | : # 这里可以等待你输入命令!
514 | ```
515 |
516 |
517 |
518 | > head 取出文件前面几行
519 |
520 | 语法:
521 |
522 | ```
523 | head [-n number] 文件
524 | ```
525 |
526 | 选项与参数:**-n** 后面接数字,代表显示几行的意思!
527 |
528 | 默认的情况中,显示前面 10 行!若要显示前 20 行,就得要这样:
529 |
530 | ```
531 | [root@kuangshen etc]# head -n 20 /etc/csh.login
532 | ```
533 |
534 |
535 |
536 | > tail 取出文件后面几行
537 |
538 | 语法:
539 |
540 | ```
541 | tail [-n number] 文件
542 | ```
543 |
544 | 选项与参数:
545 |
546 | - -n :后面接数字,代表显示几行的意思
547 |
548 | 默认的情况中,显示最后 10 行!若要显示最后 20 行,就得要这样:
549 |
550 | ```
551 | [root@kuangshen etc]# tail -n 20 /etc/csh.login
552 | ```
553 |
554 |
555 |
556 | > 拓展:Linux 链接概念
557 |
558 | Linux 链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。
559 |
560 | 情况下,**ln** 命令产生硬链接。
561 |
562 | **硬连接**
563 |
564 | 硬连接指通过索引节点来进行连接。在 Linux 的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在 Linux 中,多个文件名指向同一索引节点是存在的。比如:A 是 B 的硬链接(A 和 B 都是文件名),则 A 的目录项中的 inode 节点号与 B 的目录项中的 inode 节点号相同,即一个 inode 节点对应两个不同的文件名,两个文件名指向同一个文件,A 和 B 对文件系统来说是完全平等的。删除其中任何一个都不会影响另外一个的访问。
565 |
566 | 硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
567 |
568 | **软连接**
569 |
570 | 另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于 Windows 的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。比如:A 是 B 的软链接(A 和 B 都是文件名),A 的目录项中的 inode 节点号与 B 的目录项中的 inode 节点号不相同,A 和 B 指向的是两个不同的 inode,继而指向两块不同的数据块。但是 A 的数据块中存放的只是 B 的路径名(可以根据这个找到 B 的目录项)。A 和 B 之间是“主从”关系,如果 B 被删除了,A 仍然存在(因为两个是不同的文件),但指向的是一个无效的链接。
571 |
572 | **测试:**
573 |
574 | ```
575 | [root@kuangshen /]# cd /home
576 | [root@kuangshen home]# touch f1 # 创建一个测试文件f1
577 | [root@kuangshen home]# ls
578 | f1
579 | [root@kuangshen home]# ln f1 f2 # 创建f1的一个硬连接文件f2
580 | [root@kuangshen home]# ln -s f1 f3 # 创建f1的一个符号连接文件f3
581 | [root@kuangshen home]# ls -li # -i参数显示文件的inode节点信息
582 | 397247 -rw-r--r-- 2 root root 0 Mar 13 00:50 f1
583 | 397247 -rw-r--r-- 2 root root 0 Mar 13 00:50 f2
584 | 397248 lrwxrwxrwx 1 root root 2 Mar 13 00:50 f3 -> f1
585 | ```
586 |
587 | 从上面的结果中可以看出,硬连接文件 f2 与原文件 f1 的 inode 节点相同,均为 397247,然而符号连接文件的 inode 节点不同。
588 |
589 | ```
590 | # echo 字符串输出 >> f1 输出到 f1文件
591 | [root@kuangshen home]# echo "I am f1 file" >>f1
592 | [root@kuangshen home]# cat f1
593 | I am f1 file
594 | [root@kuangshen home]# cat f2
595 | I am f1 file
596 | [root@kuangshen home]# cat f3
597 | I am f1 file
598 | [root@kuangshen home]# rm -f f1
599 | [root@kuangshen home]# cat f2
600 | I am f1 file
601 | [root@kuangshen home]# cat f3
602 | cat: f3: No such file or directory
603 | ```
604 |
605 | 通过上面的测试可以看出:当删除原始文件 f1 后,硬连接 f2 不受影响,但是符号连接 f1 文件无效;
606 |
607 | 依此您可以做一些相关的测试,可以得到以下全部结论:
608 |
609 | - 删除符号连接f3,对f1,f2无影响;
610 | - 删除硬连接f2,对f1,f3也无影响;
611 | - 删除原文件f1,对硬连接f2没有影响,导致符号连接f3失效;
612 | - 同时删除原文件f1,硬连接f2,整个文件会真正的被删除。
613 |
614 |
--------------------------------------------------------------------------------
/Linux shell及常用36类命令汇总.md:
--------------------------------------------------------------------------------
1 | # Linux shell及常用36类命令汇总
2 |
3 | ##
4 |
5 | 使用Linux shell是一些程序员每天的基本工作,但我们经常会忘记一些有用的shell命令和技巧。当然,命令我能记住,但我不敢说能记得如何用它执行某个特定任务。需要注意一点的是,有些用法需要在你的linux系统里安装额外的软件。
6 |
7 | shell是一种命令解释器,它提供了用户和操作系统之间的交互接口。shell是面向命令行的,而 X Window 则是图形界面。你在命令行输入命令,shell进行解释,然后送往操作系统执行。
8 |
9 | shell可以执行 Linux 的系统内部命令,也可以执行应用程序。你还可以利用shell编程,执行复杂的命令程序。
10 |
11 | Linux 提供几种shell程序以供选择。常用的有 Bourne ( b s h )、C( c s h )和Korn( k s h ),各个shell都能提供基本的功能,又有其各自的特点。
12 |
13 | #### Bourne shell
14 |
15 | Bourne shell是由Steven Bourne 编写的,是UNIX 的缺省shell。Bourne shell的shell编程能力很强。但它不能处理命令的用户交互特征。bash 是Bourne shell的增强版。
16 |
17 | #### Cshell
18 |
19 | Cshell是由加利福尼亚大学伯克利分校的Bill Joy编写的。它能提供Bourne shell所不能处理的用户交互特征,如命令补全、命令别名、历史命令替换等。很多人认为, C shell的编程能力不如Bourne shell,但它的语法和C语言类似,所以C程序员将发现C shell很顺手。tcsh 是Cshell的增强版本和Cshell完全兼容。
20 |
21 | #### Korn
22 |
23 | K o r nshell是由Dave Korn 编写的。Korn shell融合了C shell和Bourne shell的优点,并和Bourne shell完全兼容。 Korn shell的效率很高,其命令交互界面和编程交互界面都很不错。Public Domain Korn shell( p d k s h )是Korn shell的增强版。
24 |
25 | #### bash
26 |
27 | bash 是大多数L i n u x系统的缺省shell。它克服了Bourne shell的缺点,又和Bourne shell完全
28 |
29 | 兼容,B a s h有以下的特点:
30 |
31 | > 1 补全命令行。 当你在bash 命令提示符下输入命令或程序名时,你不必输全命令或程序
32 | >
33 | > 名,按Tab 键,b a s h将自动补全命令或程序名。
34 | >
35 | > 2 通配符。 在b a s h下可以使用通配符 * 和?。*可以替代多个字符,而?则替代一个字符。
36 | >
37 | > 3 历史命令。 bash 能自动跟踪你每次输入的命令,并把输入的命令保存在历史列表缓冲区。
38 | >
39 | > 缓冲区的大小由HISTSIZE 变量控制。当你每次登录后,home 目录下的 .bash_history 文
40 | >
41 | > 件将初始化你的历史列表缓冲区。你也能通过history 和fc 命令执行、编辑历史命令。
42 | >
43 | > 4别名。 在b a s h下,可用alias 和unalias 命令给命令或可执行程序起别名和清除别名。这
44 | >
45 | > 样你可以用自己习惯的方式输入命令。
46 |
47 | 进入shell
48 |
49 | Linux 启动后,给出 login 命令,等待用户登录。
50 |
51 | Login: <输入用户名>
52 |
53 | Password: <输入密码>
54 |
55 | 如果是正确的用户名和密码,那么你就会进入Linux 的shell, shell给出命令提示符,等待
56 |
57 | 你输入命令。使用 l o g o u t命令退出shell。
58 |
59 | #### **shell的常用命令**
60 |
61 | ------
62 |
63 | > 1、更改帐号密码
64 |
65 | 语法:passwd
66 |
67 | Old password: <输入旧密码>
68 |
69 | New password: <输入新密码〉
70 |
71 | Retype new password: <再输入一次密码>
72 |
73 | > 2、联机帮助
74 |
75 | 语法: man 命令
76 |
77 | 例如:
78 |
79 | man ls
80 |
81 | > 3、远程登录
82 |
83 | 语法:rlogin 主机名 [-l 用户名]
84 |
85 | 例如:
86 |
87 | rlogin aa 远程登录到工作站 aa 中。
88 |
89 | rlogin aa -l user 使用 user 帐号登录到工作站 aa 中。
90 |
91 | 语法:telnet 主机名 或 telnet IP地址
92 |
93 | 例如:
94 |
95 | telnet aa
96 |
97 | telnet 130.129.21.250
98 |
99 | > 3、文件或目录处理
100 |
101 | 列出文件或目录下的文件名。
102 |
103 | 语法: ls [-atFlgR] [name]
104 |
105 | ls 列出目前目录下的文件名。
106 |
107 | ls -a 列出包括以 .开始的隐藏文件的所有文件名。
108 |
109 | ls -t 依照文件最后修改时间的顺序列出文件名。
110 |
111 | ls -F 列出当前目录下的文件名及其类型。以/ 结尾表示为目录名,以* 结尾表示为
112 |
113 | 可执行文件,以@ 结尾表示为符号连接。
114 |
115 | ls -l 列出目录下所有文件的权限、所有者、文件大小、修改时间及名称。
116 |
117 | ls -lg 同上,并显示出文件的所有者工作组名。
118 |
119 | ls -R 显示出目录下以及其所有子目录的文件名。
120 |
121 | > 4、改变工作目录
122 |
123 | 语法:cd [name]
124 |
125 | name:目录名、路径或目录缩写。
126 |
127 | 例如:
128 |
129 | cd 改变目录位置至用户登录时的工作目录。
130 |
131 | cd dir 改变目录位置至d i r目录下。
132 |
133 | cd user 改变目录位置至用户的工作目录。
134 |
135 | cd .. 改变目录位置至当前目录的父目录。
136 |
137 | cd ../user 改变目录位置至相对路径 user 的目录下。
138 |
139 | cd /../.. 改变目录位置至绝对路径的目录位置下。
140 |
141 | cd 改变目录位置至用户登录时的工作目录。
142 |
143 | > 5、复制文件
144 |
145 | 语法: cp [-r] 源地址 目的地址
146 |
147 | 例如:
148 |
149 | cp file1 file2 将文件 file1 复制成 f i l e 2。
150 |
151 | cp file1 dir1 将文件 file1 复制到目录 dir1 下,文件名仍为 f i l e 1。
152 |
153 | cp /tmp/file1 . 将目录 /tmp 下的文件 file1 复制到当前目录下,文件名仍为 f i l e 1。
154 |
155 | cp /tmp/file1 file2 将目录 /tmp 下的文件 file1 复制到当前目录下,文件名为f i l e 2。
156 |
157 | cp -r dir1 dir2 复制整个目录。
158 |
159 | > 6、移动或更改文件、目录名称
160 |
161 | 语法:mv 源地址 目的地址
162 |
163 | 例如:
164 |
165 | mv file1 file2 将文件 f i l e 1更名为 f i l e 2。
166 |
167 | mv file1 dir1 将文件 f i l e 1移到目录 dir1 下,文件名仍为 f i l e 1。
168 |
169 | mv dir1 dir2 将目录 dir1 更改为目录 d i r 2。
170 |
171 | > 7、建立新目录
172 |
173 | 语法: mkdir 目录名
174 |
175 | mkdir dira 建立一新目录 d i ra。
176 |
177 | > 8、删除目录
178 |
179 | 语法: rmdir 目录名 或 rm 目录名
180 |
181 | 例如:
182 |
183 | rmdir dir1 删除目录 d i r 1,但 dir1 下必须没有文件存在,否则无法删除。
184 |
185 | rm -r dir1 删除目录 d i r 1及其子目录下所有文件。
186 |
187 | > 9、删除文件
188 |
189 | 语法: rm 文件名
190 |
191 | 例如:
192 |
193 | rm file1 删除文件名为 file1 的文件。
194 |
195 | rm file? 删除文件名中有五个字符且前四个字符为file 的所有文件。
196 |
197 | rm f* 删除文件名中以 f 为字首的所有文件。
198 |
199 | > 10、列出当前所在的目录位置
200 |
201 | 语法: p w d
202 |
203 | > 11、查看文件内容
204 |
205 | 语法: cat 文件名
206 |
207 | 例如:
208 |
209 | cat file1 以连续显示方式,查看文件名 file1 的内容。
210 |
211 | > 12、分页查看文件内容
212 |
213 | 语法: more 文件名 或 cat 文件名 | more
214 |
215 | 例如:
216 |
217 | more file1 以分页方式查看文件名 file1 的内容。
218 |
219 | cat file1 | more 以分页方式查看文件名 file1 的内容。
220 |
221 | > 13、查看目录所占磁盘容量
222 |
223 | 语法: du [-s] 目录
224 |
225 | 例如:
226 |
227 | du dir1 显示目录 dir1 的总容量及其子目录的容量(以KB 为单位)。
228 |
229 | du -s dir1 显示目录 dir1 的总容量。
230 |
231 | > 14、文件传输
232 |
233 | \1. 拷贝文件或目录至远程工作站
234 |
235 | 语法: rcp [-r] 源地址 主机名:目的地址
236 |
237 | 源地址文件名、目录名或路径。
238 |
239 | 例如:
240 |
241 | rcp file1 doc:/home/user 将文件f i l e 1拷贝到工作站 doc 路径 /home/user 下。
242 |
243 | rcp -r dir1 doc:/home/user 将目录 d i r 1拷贝到工作站 doc 路径/home/user 下。
244 |
245 | \2. 自远程工作站,拷贝文件或目录
246 |
247 | 语法: rcp [-r] 主机名:源地址 目的地址
248 |
249 | 主机名工作站名。
250 |
251 | 源地址路径名。
252 |
253 | 目的地址、文件名、目录名或路径 。
254 |
255 | 例如:
256 |
257 | rcp doc:/home/user/file1 file2 将工作站 d o c路径/home/user 下的目录 d i r 1,拷贝到当前工
258 |
259 | 作站的目录下,目录名仍为 d i r 1。
260 |
261 | rcp -r doc:/home/user/dir1 . 将工作站doc 路径/home/user 下的目录 d i r 1,拷贝到当前工
262 |
263 | 作站的目录下,目录名仍为 d i r 1。
264 |
265 | \3. 本地工作站与远程工作站之间的文件传输
266 |
267 | 必须拥有远程工作站的帐号及密码,才可进行传输工作。
268 |
269 | 语法: ftp 主机名 或 ftp ip地址
270 |
271 | 例如:
272 |
273 | ftp doc 与远程工作站 doc 之间进行文件传输。
274 |
275 | Name (doc:user-name): <输入帐号>
276 |
277 | Password (doc:user-password): <输入密码>
278 |
279 | ftp> help 列出 ftp 文件传输时可使用的命令。
280 |
281 | ftp> !ls 列出本地工作站当前目录下的所有文件名。
282 |
283 | ftp> !pwd 列出本地工作站当前所在的目录位置。
284 |
285 | ftp> ls 列出远程工作站当前目录下的所有文件名。
286 |
287 | ftp> dir 列出远程工作站当前目录下的所有文件名。
288 |
289 | ftp> dir . |more 分页列出远程工作站当前目录下的所有文件名。
290 |
291 | ftp> pwd 列出远程工作站当前所在的目录位置。
292 |
293 | ftp> cd dir1 更改远程工作站的工作目录位置至 dir1 之下。
294 |
295 | ftp> get file1 将远程工作站的文件 f i l e 1拷贝到本地工作站中。
296 |
297 | ftp> put file2 将本地工作站的文件 f i l e 2拷贝到远程工作站中。
298 |
299 | ftp> mget *.c 将远程工作站中扩展文件名为 c 的所有文件拷贝到本地工作站中。
300 |
301 | ftp> mput *.txt 将本地工作站中扩展文件名为 txt 的所有文件拷贝到远程工作站中。
302 |
303 | ftp> prompt 切换交互式指令(使用 mput/mget 时不是每个文件皆询问y e s / n o )。
304 |
305 | ftp> quit 结束 ftp 工作。
306 |
307 | ftp> bye 结束 ftp 工作。
308 |
309 | 注意 从PC与工作站间的文件传输也可透过在 PC端的 FTP指令进行文件传输,指令用
310 |
311 | 法与上述指令大致相同。
312 |
313 | > 15、文件权限的设定
314 |
315 | \1. 改变文件或目录的读、写、执行权限
316 |
317 | 语法:chmod [-R] mode name
318 |
319 | n a m e :文件名或目录名。
320 |
321 | mode: 3个8位数字或r w x的组合。r- r e a d (读),w - w r i t e (写),x - e x e c u t e (执行),u - u s e r (当前用
322 |
323 | 户),g - g r o u p(组) ,o - o t h e r(其他用户) 。
324 |
325 | 例如:
326 |
327 | chmod 755 dir1 对于目录d i r 1,设定成任何使用者皆有读取及执行的权利,但只有所
328 |
329 | 有者可做修改。
330 |
331 | chmod 700 file1 对于文件f i l e 1,设定只有所有者可以读、写和执行的权利。
332 |
333 | chmod u+x file2 对于文件f i l e 2,增加当前用户可以执行的权利。
334 |
335 | chmod g+x file3 对于文件f i l e 3,增加工作组使用者可执行的权利。
336 |
337 | chmod o-r file4 对于文件f i l e 4,删除其他使用者可读取的权利。
338 |
339 | 2.改变文件或目录的所有权
340 |
341 | 语法:chown [-R] 用户名 name
342 |
343 | n a m e:文件名或目录名。
344 |
345 | 例如 :
346 |
347 | chown user file1 将文件 file1 改为用户user 所有。
348 |
349 | chown -R user dir1 将目录 d i r 1及其子目录下面的所有文件改为用户user 所有。
350 |
351 | > 16、检查自己所属的工作组名称
352 |
353 | 语法:g r o u p s
354 |
355 | > 17、 改变文件或目录工作组所有权
356 |
357 | 语法:chgrp [-R] 工作组名 name
358 |
359 | n a m e:文件名或目录名
360 |
361 | 例如:
362 |
363 | chgrp vlsi file1 将文件 file1 的工作组所有权改为 vlsi 工作组所有。
364 |
365 | chgrp -R image dir1 将目录d i r 1及其子目录下面的所有文件,改为 image 工作组所有。
366 |
367 | > 18、 改变文件或目录的最后修改时间
368 |
369 | 语法:touch name
370 |
371 | n a m e:文件名或目录名。
372 |
373 | > 19、文件的链接
374 |
375 | 同一文件,可拥有一个以上的名称,也就是把一个文件进行链接。
376 |
377 | 语法:ln 老文件名 新文件名
378 |
379 | 例如 :
380 |
381 | ln file1 file2 将文件 f i l e 2链接至文件 f i l e 1。
382 |
383 | 语法:ln -s 老文件名 新文件名
384 |
385 | 例如 :
386 |
387 | ln -s file3 file4 将文件 file4 链接至文件f i l e 3。
388 |
389 | > 20、文件中字符串的查寻
390 |
391 | 语法:grep string file
392 |
393 | 例如 :
394 |
395 | grep abc file1 寻找文件f i l e 1中包含字符串 abc 所在行的文本内容。
396 |
397 | 查寻文件或命令的路径
398 |
399 | 语法:whereis command 显示命令的路径。
400 |
401 | 语法:which command 显示命令的路径,及使用者所定义的别名。
402 |
403 | 语法:whatis command 显示命令功能的摘要。
404 |
405 | 语法:find search-path -name filename -print 搜寻指定路径下某文件的路径 。
406 |
407 | 例如 :
408 |
409 | find / -name file1 -print 自根目录下寻找文件 file1 的路径。
410 |
411 | > 21、比较文件或目录的内容
412 |
413 | 语法:d i ff [-r] name1 name2
414 |
415 | name1 name2:可同时为文件名或目录名。
416 |
417 | 例如:
418 |
419 | d i ff file1 file2 比较文件file1 与 file2 内各行的不同之处。
420 |
421 | d i ff -r dir1 dir2 比较目录 dir1 与 dir2 内各文件的不同之处。
422 |
423 | > 22、文件打印输出
424 |
425 | 用户可用 .login 文件中的 setenv PRINTER来设定打印机名。
426 |
427 | 例如 :
428 |
429 | setenv PRINTER sp 设定自 sp 打印机打印资料。
430 |
431 | 一般文件的打印
432 |
433 | 语法:lpr [-P打印机名] 文件名
434 |
435 | 例如:
436 |
437 | lpr file1 或 lpr -Psp file1 自 s p打印机打印文件 f i l e 1。
438 |
439 | 语法:enscript [-P打印机名] 文件名
440 |
441 | 例如:
442 |
443 | enscript file3 或 enscript -Psp file3 自 s p打印机打印文件 f i l e 3。
444 |
445 | > 23、troff 文件的打印
446 |
447 | 语法:p t r o ff [-P打印机名] [-man][-ms] 文件名
448 |
449 | 例如:
450 |
451 | ptroff -Psp -man /usr/man/man1/lpr1 以troff 格式,自 sp 打印机打印lpr1 命令的使用说明。
452 |
453 | 打印机控制命令
454 |
455 | 1.检查打印机状态、打印作业顺序号和用户名
456 |
457 | 第2章计shell及常用命令计计 15
458 |
459 | 下载
460 |
461 | 语法:lpq [-P打印机名]
462 |
463 | 例如:
464 |
465 | lpq 或 lpq -Psp 检查 sp 打印机的状态。
466 |
467 | \2. 删除打印机内的打印作业( 用户仅可删除自己的打印作业 )
468 |
469 | 语法:lprm [-P打印机名] 用户名 或 作业编号
470 |
471 | 例如:
472 |
473 | lprm user或lprm -Psp user 删除s p打印机中用户user 的打印作业,此时用户名必须为u s e r。
474 |
475 | lprm -Psp 456 删除 sp 打印机上编号为 456 的打印作业。
476 |
477 | > 24、进程控制
478 |
479 | 1.查看系统中的进程
480 |
481 | 语法:ps [-aux]
482 |
483 | 例如:
484 |
485 | p s或ps -x 查看系统中,属于自己的进程。
486 |
487 | ps -au 查看系统中,所有用户的进程。
488 |
489 | ps -aux 查看系统中,包含系统内部的及所有用户的进程。
490 |
491 | \2. 结束或终止进程
492 |
493 | 语法:kill [-9] PID
494 |
495 | P I D:利用 ps 命令所查出的进程号。
496 |
497 | 例如:
498 |
499 | kill 456或kill -9 456 终止进程号为 456 的进程。
500 |
501 | \3. 在后台执行进程的方式
502 |
503 | 语法:命令 &
504 |
505 | 例如:
506 |
507 | cc file1.c & 将编译 file1.c 文件的工作置于后台执行。
508 |
509 | 语法:按下 C o n t r o l + Z键,暂停正在执行的进程。键入b g命令,将暂停的进程置于后台继
510 |
511 | 续执行。
512 |
513 | 例如:
514 |
515 | cc file2.c
516 |
517 | ^ Z
518 |
519 | S t o p p e d
520 |
521 | b g
522 |
523 | \4. 查看正在后台中执行的进程
524 |
525 | 语法:j o b s
526 |
527 | \5. 结束或终止后台中的进程
528 |
529 | 语法:kill %n
530 |
531 | n:利用j o b s命令查看出的后台作业号
532 |
533 | 例如:
534 |
535 | kill % 终止在后台中的第一个进程。
536 |
537 | kill %2 终止在后台中的第二个进程。
538 |
539 | > 25、shell变量
540 |
541 | \1. 查看shell变量的设定值
542 |
543 | 语法:set 查看所有shell变量的设定值。
544 |
545 | 语法:echo $变量名 显示指定的shell变量的设定值。
546 |
547 | \2. 设定shell变量
548 |
549 | 语法:set var = value
550 |
551 | 例如:
552 |
553 | set term=vt100 设定shell变量 t e r m为 VT100 型终端。
554 |
555 | \3. 删除shell变量
556 |
557 | 语法:unset var
558 |
559 | 例如:
560 |
561 | unset PRINTER 删除shell变量 PRINTER 的设定值。
562 |
563 | > 26、别名
564 |
565 | \1. 查看所定义的命令的别名
566 |
567 | 语法: a l i a s 查看自己目前定义的所有命令,及所对应的别名。
568 |
569 | 语法: alias name 查看指定的name 命令的别名。
570 |
571 | 例如:
572 |
573 | alias dir 查看别名 dir 所定义的命令。
574 |
575 | ls -atl
576 |
577 | \2. 定义命令的别名
578 |
579 | 语法: alias name‘command line’
580 |
581 | 例如:
582 |
583 | alias dir ‘ls -l’ 将命令 ls - l 定义别名为 d i r。
584 |
585 | \3. 删除所定义的别名
586 |
587 | 语法: unalias name
588 |
589 | 例如:
590 |
591 | unalias dir 删除别名 dir 的定义。
592 |
593 | unalias * 删除所有别名的设定。
594 |
595 | > 27、历史命令
596 |
597 | \1. 设定命令记录表的长度
598 |
599 | 语法: set history = n
600 |
601 | 例如:
602 |
603 | set history = 40 设定命令记录表的长度为 40 (可记录执行过的前面 40 个命令)。
604 |
605 | \2. 查看命令记录表的内容
606 |
607 | 语法: h i s t o r y
608 |
609 | \3. 使用命令记录表
610 |
611 | 语法: !! 重复执行前一个命令。
612 |
613 | 语法: ! n
614 |
615 | n:命令记录表的命令编号。
616 |
617 | 语法: ! s t r i n g 重复前面执行过的以 string 为起始字符串的命令。
618 |
619 | 例如: ! c a t 重复前面执行过的以 cat 为起始字符串的命令。
620 |
621 | \4. 显示前一个命令的内容
622 |
623 | 语法: ! !:p
624 |
625 | \5. 更改前一个命令的内容并执行
626 |
627 | 语法: ^oldstring ^newstring 将前一个命令中 oldstring 的部份改成 n e w s t r i n g并执
628 |
629 | 行。
630 |
631 | 例如:
632 |
633 | find . -name file1.c -print
634 |
635 | ^ f i l e 1 . c ^ c o r e
636 |
637 | find . -name core -print
638 |
639 | > 28、文件的压缩
640 |
641 | \1. 压缩文件
642 |
643 | 语法:compress 文件名 压缩文件
644 |
645 | 语法:compressdir 目录名 压缩目录
646 |
647 | \2. 解压缩文件
648 |
649 | 语法:uncompress 文件名 解压缩文件
650 |
651 | 语法:uncompressdir 目录名 解压缩目录
652 |
653 | > 29、管道命令的使用
654 |
655 | 语法:命令1 | 命令2 将命令1的执行结果送到命令2,做为命令2的输入。
656 |
657 | 例如:
658 |
659 | ls -Rl | more 以分页方式列出当前目录及其子目录下所有文件的名称。
660 |
661 | cat file1 | more 以分页方式列出文件 file1 的内容。
662 |
663 | 30、输入/输出控制
664 |
665 | \1. 标准输入的控制
666 |
667 | 语法:命令 < 文件 将文件做为命令的输入。
668 |
669 | 例如:
670 |
671 | mail -s “mail test” 电子邮件地址 < file1 将文件file 当做信件的内容,主
672 |
673 | 题名称为 mail test,送给收信人。
674 |
675 | \2. 标准输出的控制
676 |
677 | 语法:命令 > 文件 将命令的执行结果送至指定的文件中。
678 |
679 | 例如:
680 |
681 | ls -l > list 将执行 “ls -l” 命令的结果写入文件list 中。
682 |
683 | 语法:命令>! 文件 将命令的执行结果送至指定的文件中,若文件已经存在,则覆盖。
684 |
685 | 例如:
686 |
687 | ls -lg >! list 将执行 “ls - lg” 命令的结果覆盖写入文件 list 中。
688 |
689 | 语法:命令 >& 文件 将命令执行时屏幕上所产生的任何信息写入指定的文件中。
690 |
691 | 例如:
692 |
693 | cc file1.c >& error 将编译 file1.c 文件时所产生的任何信息写入文件 error 中。
694 |
695 | 语法:命令>> 文件 将命令执行的结果附加到指定的文件中。
696 |
697 | 例如:
698 |
699 | ls - lag >> list 将执行 “ls - lag” 命令的结果附加到文件 list 中。
700 |
701 | 语法:命令 >>& 文件 将命令执行时屏幕上所产生的任何信息附加到指定的文件中。
702 |
703 | 例如:
704 |
705 | cc file2.c >>& error 将编译 file2.c 文件时屏幕所产生的任何信息附加到文件error 中。
706 |
707 | > 31、查看系统中的用户
708 |
709 | 语法: who 或 f i n g e r
710 |
711 | 语法: w
712 |
713 | 语法: finger 用户名 或 finger 用户名@域名
714 |
715 | 改变用户名
716 |
717 | 语法: su 用户名
718 |
719 | 例如:
720 |
721 | su user 进入用户user 的帐号。
722 |
723 | p a s s w r o d : <输入用户user 的密码>
724 |
725 | > 32、查看用户名
726 |
727 | 语法: who am i 查看登录时的用户名。
728 |
729 | 语法: w h o a m i 查看当前的用户名。若已执行过s u命令,则显示出此用户的用
730 |
731 | 户名。
732 |
733 | > 33、查看当前系统上所有工作站的用户
734 |
735 | 语法: rusers
736 |
737 | 按Ctrl+C> 结束
738 |
739 | > 34、与某工作站上的用户交谈
740 |
741 | 语法: talk 用户名@主机名或talk 用户名@ I P地址
742 |
743 | 例如:
744 |
745 | \1) 可先利用 rusers 指令查看网络上的用户;
746 |
747 | \2) 假设自己的帐号是 ddd ,在工作站 aaa上使用,现在想要与 bbb 上的ccc 交谈。
748 |
749 | talk ccc@bbb
750 |
751 | 可按Ct r l + C结束。
752 |
753 | > 35、检查网络是否连通
754 |
755 | 语法:ping 主机名或ping IP地址
756 |
757 | > 36、电子邮件的使用简介
758 |
759 | \1. 将文件当做电子邮件的内容送出
760 |
761 | 语法:mail -s “主题”电子邮件地址 < 文件
762 |
763 | 例如:
764 |
765 | mail -s “hello” 电子邮件地址 < file.c
766 |
767 | \2. 传送电子邮件给本系统用户
768 |
769 | 语法:mail 用户名
770 |
771 | \3. 传送电子邮件至外地用户
772 |
773 | 语法: mail 电子邮件地址
774 |
775 | 例如:
776 |
777 | mail xxx@163.com
778 |
779 | Subject : mail test
780 |
781 | :
782 |
783 | 按下 Ctrl+D 键或 . 键结束正文。
784 |
785 | 连按两次C t r l + C键则中断工作,不送此信件。
786 |
787 | Cc( Carbon copy) : 复制一份正文,给其他的收信人。
788 |
789 | \3. 检查所传送的电子邮件是否送出,或滞留在邮件服务器中
790 |
791 | 语法:/usr/magedu/sendmail -bp
792 |
793 | 若屏幕显示为 “Mail queue is empty” 的信息,表示 mail 已送出。
794 |
795 | 若为其他错误信息,表示电子邮件因故尚未送出。
796 |
797 |
798 |
799 | 原文地址:https://mp.weixin.qq.com/s/euh8YCm5IQN7pTm5JVObjA
800 |
--------------------------------------------------------------------------------
/40 个简单又有效的 Linux Shell 脚本示例.md:
--------------------------------------------------------------------------------
1 | 原文地址:https://blog.csdn.net/weixin_38889300/article/details/129828412
2 |
3 |
4 |
5 | # 40 个简单又有效的 Linux Shell 脚本示例
6 |
7 |
8 |
9 | 历史上,shell 一直是类 Unix 系统的本地命令行解释器。它已被证明是 Unix 的主要功能之一,并发展成为一个全新的主题。Linux 提供了各种功能强大的 shell,包括 Bash、Zsh、Tcsh 和 Ksh。这些外壳最令人惊讶的特性之一是其可编程性。创建简单而有效的 Linux shell 脚本来处理日常工作非常容易。
10 |
11 | ## 1.Hello World
12 |
13 | 程序员经常通过学习 hello world 程序来学习新语言。这是一个简单的程序,将字符串 “HelloWorld” 打印到标准输出中。然后,使用 vim 或 nano 等编辑器创建 hello-world.sh 文件,并将以下行复制到其中。
14 |
15 | ```
16 | #!/bin/bash
17 | echo "Hello World"
18 | ```
19 |
20 | 保存并退出文件。接下来,您需要使用以下命令使该文件可执行。
21 |
22 | ```
23 | $ chmod a+x hello-world.sh
24 | ```
25 |
26 | 可以使用以下两个命令中的任何一个来运行此命令。
27 |
28 | ```
29 | $ bash hello-world.sh
30 | $ ./hello-world.sh
31 | ```
32 |
33 | 它将打印出传递给脚本内部回显的字符串。
34 |
35 | ## 2.使用 echo 打印
36 |
37 | echo 命令用于在 bash 中打印信息。它类似于 C 函数 “printf”,并提供了许多常见选项,包括转义序列和重定向。将以下行复制到名为 echo.sh 的文件中,并使其可执行,如上所述。
38 |
39 | ```
40 | #!/bin/bash
41 | echo "Printing text"
42 | echo -n "Printing text without newline"
43 | echo -e "\nRemoving \t special \t characters\n"
44 | ```
45 |
46 | 运行脚本以查看其功能。-e 选项用于告诉 echo 传递给它的字符串包含特殊字符,需要扩展功能。
47 |
48 | ## 3.使用注释
49 |
50 | 注释对文档很有用,是高质量代码库的要求。将注释放在处理关键逻辑的代码中是一种常见的做法。要注释掉一行,只需在其前面使用 #(hash)字符。例如,请查看下面的 bash 脚本示例。
51 |
52 | ```
53 | #!/bin/bash
54 |
55 | # Adding two values
56 | ((sum=25+35))
57 |
58 | #Print the result
59 | echo $sum
60 | ```
61 |
62 | 此脚本将输出数字 60。首先,在某些行之前使用 #检查注释的使用方式。不过,第一行是一个例外。它被称为 shebang,让系统知道在运行这个脚本时要使用哪个解释器。
63 |
64 | ## 4.多行注释
65 |
66 | 许多人使用多行注释来记录他们的 shell 脚本。在下一个名为 comment.sh 的脚本中检查这是如何完成的。
67 |
68 | ```
69 | #!/bin/bash
70 | : '
71 | This script calculates
72 | the square of 5.
73 | '
74 | ((area=5*5))
75 | echo $area
76 | ```
77 |
78 | 注意多行注释是如何放置在内部的:“和” 字符。
79 |
80 | ## 5.While 循环
81 |
82 | while 循环构造用于多次运行某些指令。查看以下名为 while.sh 的脚本,以更好地理解此概念。
83 |
84 | ```
85 | #!/bin/bash
86 | i=0
87 |
88 | while [ $i -le 2 ]
89 | do
90 | echo Number: $i
91 | ((i++))
92 | done
93 |
94 | 因此,while 循环采用以下形式。
95 |
96 | while [ condition ]
97 | do
98 | commands 1
99 | commands n
100 | done
101 | ```
102 |
103 | 方括号周围的空格是必填的。
104 |
105 | ## 6.For 循环
106 |
107 | for 循环是另一种广泛使用的 bashshell 构造,它允许用户高效地迭代代码。下面演示了一个简单的示例。
108 |
109 | ```
110 | #!/bin/bash
111 |
112 | for (( counter=1; counter<=10; counter++ ))
113 | do
114 | echo -n "$counter "
115 | done
116 |
117 | printf "\n"
118 | ```
119 |
120 | ## 7.接收用户输入
121 |
122 | ```
123 | #!/bin/bash
124 |
125 | echo -n "Enter Something:"
126 | read something
127 |
128 | echo "You Entered: $something"
129 | ```
130 |
131 | ## 8.If 语句
132 |
133 | ```
134 | if CONDITION
135 | then
136 | STATEMENTS
137 | fi
138 | ```
139 |
140 | 只有当条件为真时,才会执行这些语句。fi 关键字用于标记 if 语句的结尾。下面显示了一个快速示例。
141 |
142 | ```
143 | > #!/bin/bash
144 | > echo -n "Enter a number:"
145 | > read num
146 | > if [[$num -gt 10]]
147 | > then
148 | > echo "Number is greater than 10."
149 | > fi
150 | ```
151 |
152 | 如果通过输入提供的数字大于 10,上述程序将仅显示输出。-gt 表示大于;类似地 - lt 表示小于 - le 表示小于等于;且 - ge 表示大于等于。此外,还需要 [[]]。
153 |
154 | ## 9.使用 If Else 进行更多控制
155 |
156 | 将 else 构造与 if 结合起来,可以更好地控制脚本的逻辑。下面显示了一个简单的示例。
157 |
158 | ```
159 | #!/bin/bash
160 |
161 | read n
162 | if [ $n -lt 10 ];
163 | then
164 | echo "It is a one digit number"
165 | else
166 | echo "It is a two digit number"
167 | fi
168 | ```
169 |
170 | 其他部分需要放在 if 的动作部分之后和 fi 之前。
171 |
172 | ## 10.使用 AND 运算符
173 |
174 | AND 运算符允许我们的程序检查是否同时满足多个条件。由 AND 运算符分隔的所有部分必须为 true。否则,包含 AND 的语句将返回 false。查看下面的 bash 脚本示例,以更好地了解 AND 的工作原理。
175 |
176 | ```
177 | #!/bin/bash
178 |
179 | echo -n "Enter Number:"
180 | read num
181 |
182 | if [[ ( $num -lt 10 ) && ( $num%2 -eq 0 ) ]]; then
183 | echo "Even Number"
184 | else
185 | echo "Odd Number"
186 | fi
187 | ```
188 |
189 | AND 运算符由 && 符号表示。
190 |
191 | ## 11.使用 OR 运算符
192 |
193 | OR 运算符是另一个关键的构造,它允许我们在脚本中实现复杂、健壮的编程逻辑。与 AND 相反,当 OR 运算符的任一操作数为真时,由 OR 运算符组成的语句返回真。仅当由 OR 分隔的每个操作数为假时,它才返回假。
194 |
195 | ```
196 | #!/bin/bash
197 |
198 | echo -n "Enter any number:"
199 | read n
200 |
201 | if [[ ( $n -eq 15 || $n -eq 45 ) ]]
202 | then
203 | echo "You won"
204 | else
205 | echo "You lost!"
206 | fi
207 | ```
208 |
209 | 这个简单的示例演示了 OR 运算符如何在 Linuxshell 脚本中工作。只有当用户输入数字 15 或 45 时,它才会宣布用户为获胜者。|| 符号表示 OR 运算符。
210 |
211 | ## 12.使用 El if
212 |
213 | elif 语句代表 else if,并为实现链逻辑提供了一种方便的方法。通过评估以下示例,了解 elif 的工作原理。
214 |
215 | ```
216 | #!/bin/bash
217 |
218 | echo -n "Enter a number: "
219 | read num
220 |
221 | if [[ $num -gt 10 ]]
222 | then
223 | echo "Number is greater than 10."
224 | elif [[ $num -eq 10 ]]
225 | then
226 | echo "Number is equal to 10."
227 | else
228 | echo "Number is less than 10."
229 | fi
230 | ```
231 |
232 | 上面的程序是不言自明的,所以我们不会逐行剖析它。相反,更改脚本中的变量名称和值等部分,以检查它们如何一起工作。
233 |
234 | ## 13.case 条件
235 |
236 | . switch 构造是 Linux bash 脚本提供的另一个强大功能。它可以用于需要嵌套条件的地方,但不希望使用复杂的 if-else elif 链。看看下一个例子。
237 |
238 | ```
239 | #!/bin/bash
240 |
241 | echo -n "Enter a number: "
242 | read num
243 |
244 | case $num in
245 | 100)
246 | echo "Hundred!!" ;;
247 | 200)
248 | echo "Double Hundred!!" ;;
249 | *)
250 | echo "Neither 100 nor 200" ;;
251 | esac
252 | ```
253 |
254 | 条件写在 case 和 esac 关键字之间。*)用于匹配除 100 和 200 以外的所有输入。
255 |
256 | ## 14.命令行参数
257 |
258 | 在许多情况下,直接从命令 shell 获取参数是有益的。下面的示例演示了如何在 bash 中执行此操作。
259 |
260 | ```
261 | #!/bin/bash
262 | echo "Total arguments : $#"
263 | echo "First Argument = $1"
264 | echo "Second Argument = $2"
265 | ```
266 |
267 | 运行此脚本时,在其名称后添加两个附加参数。我将其命名为 test.sh,调用过程概述如下。
268 |
269 | ```
270 | $ ./test.sh Hey Howdy
271 | ```
272 |
273 | 因此,1、用于访问第一个参数;2、用于访问第二个参数,依此类推。最后,3、用于获取参数总数。
274 |
275 | ## 15.使用名称获取参数
276 |
277 | 下面的示例显示了如何获取带有名称的命令行参数。
278 |
279 | ```
280 | #!/bin/bash
281 |
282 | for arg in "$@"
283 | do
284 | index=$(echo $arg | cut -f1 -d=)
285 | val=$(echo $arg | cut -f2 -d=)
286 | case $index in
287 | X) x=$val;;
288 | Y) y=$val;;
289 | *)
290 | esac
291 | done
292 | ((result=x+y))
293 | echo "X+Y=$result"
294 | ```
295 |
296 | 将此脚本命名为 test.sh,并按如下所示调用它。
297 |
298 | ```
299 | $ ./test.sh X=44 Y=100
300 | ```
301 |
302 | 它应该返回 X+Y=144。这里的参数存储在 “$@” 中,脚本使用 Linuxcut 命令获取它们。
303 |
304 | ## 16.连接字符串
305 |
306 | 字符串处理对于广泛的现代 bash 脚本来说非常重要。值得庆幸的是,它在 bash 中更加舒适,并允许以更精确、简洁的方式实现这一点。请参见下面的示例,了解 bash 字符串连接。
307 |
308 | ```
309 | #!/bin/bash
310 |
311 | string1="Ubuntu"
312 | string2="Pit"
313 | string=$string1$string2
314 | echo "$string is a great resource for Linux beginners."
315 | ```
316 |
317 | ## 17.字符串截取
318 |
319 | 与许多编程语言不同,bash 不提供任何用于剪切字符串部分的内置函数。然而,下面的示例演示了如何使用参数展开来实现这一点。
320 |
321 | ```
322 | #!/bin/bash
323 | Str="Learn Bash Commands from UbuntuPit"
324 | subStr=${Str:0:20}
325 | echo $subStr
326 | ```
327 |
328 | 该脚本应打印出 “学习 Bash 命令” 作为其输出。参数展开形式为 ${VAR_NAME:S:L}。这里,S 表示起始位置,L 表示长度。
329 |
330 | ## 18.使用 cut 做截取
331 |
332 | 可以在脚本中使用 Linux cut 命令来截取字符串的一部分,也就是子字符串。下一个示例显示了如何做到这一点。
333 |
334 | ```
335 | #!/bin/bash
336 | Str="Learn Bash Commands from UbuntuPit"
337 | #subStr=${Str:0:20}
338 |
339 | subStr=$(echo $Str| cut -d ' ' -f 1-3)
340 | echo $subStr
341 | ```
342 |
343 | ## 19.添加两个值
344 |
345 | 在 Linux shell 脚本中执行算术运算非常容易。下面的示例演示了如何从用户接收两个数字作为输入并将它们相加。
346 |
347 | ```
348 | #!/bin/bash
349 | echo -n "Enter first number:"
350 | read x
351 | echo -n "Enter second number:"
352 | read y
353 | (( sum=x+y ))
354 | echo "The result of addition=$sum"
355 | ```
356 |
357 | 如您所见,在 bash 中添加数字相当简单。
358 |
359 | ## 20.添加多个值
360 |
361 | 您可以使用循环获取多个用户输入并将其添加到脚本中。以下示例显示了这一点。
362 |
363 | ```
364 | #!/bin/bash
365 | sum=0
366 | for (( counter=1; counter<5; counter++ ))
367 | do
368 | echo -n "Enter Your Number:"
369 | read n
370 | (( sum+=n ))
371 | #echo -n "$counter "
372 | done
373 | printf "\n"
374 | echo "Result is: $sum"
375 | ```
376 |
377 | 但是,省略 (()) 将导致字符串串联而不是相加。所以,在你的程序中检查类似的情况。
378 |
379 | ## 21.Bash 中的函数
380 |
381 | 与任何编程方言一样,函数在 Linux shell 脚本中扮演着重要角色。它们允许管理员创建自定义代码块以供频繁使用。下面的演示将概述函数如何在 Linux bash 脚本中工作。
382 |
383 | ```
384 | #!/bin/bash
385 | function Add()
386 | {
387 | echo -n "Enter a Number: "
388 | read x
389 | echo -n "Enter another Number: "
390 | read y
391 | echo "Adiition is: $(( x+y ))"
392 | }
393 |
394 | Add
395 | ```
396 |
397 | 这里我们像以前一样添加了两个数字。但在这里,我们使用了一个名为 Add 的函数来完成这项工作。因此,每当您需要再次添加时,只需调用此函数,而不必再次编写该部分。
398 |
399 | ## 22.具有返回值的函数
400 |
401 | 最神奇的功能之一是允许数据从一个函数传递到另一个函数。它在各种场景中都很有用。查看下一个示例。
402 |
403 | ```
404 | #!/bin/bash
405 |
406 | function Greet() {
407 |
408 | str="Hello $name, what brings you to UbuntuPit.com?"
409 | echo $str
410 | }
411 |
412 | echo "-> what's your name?"
413 | read name
414 |
415 | val=$(Greet)
416 | echo -e "-> $val"
417 | ```
418 |
419 | 这里,输出包含从 Greet()函数接收的数据。
420 |
421 | ## 23.从 Bash 脚本创建目录
422 |
423 | 使用 shell 脚本运行系统命令的能力使开发人员的工作效率大大提高。下面的简单示例将向您展示如何在 shell 脚本中创建目录。
424 |
425 | ```
426 | #!/bin/bash
427 | echo -n "Enter directory name ->"
428 | read newdir
429 | cmd="mkdir $newdir"
430 | eval $cmd
431 | ```
432 |
433 | 该脚本只需调用标准 shell 命令 mkdir,并在仔细查看时将目录名传递给它。这个程序应该在文件系统中创建一个目录。您还可以传递命令以在 backticks(“)内部执行,如下所示。
434 |
435 | ```
436 | `mkdir $newdir`
437 | ```
438 |
439 | ## 24.确认存在后创建目录
440 |
441 | 如果当前工作目录中已包含同名文件夹,则上述程序将无法运行。例如,下面的程序将检查是否存在名为 $dir 的文件夹,如果找不到,则只创建一个。
442 |
443 | ```
444 | #!/bin/bash
445 | echo -n "Enter directory name ->"
446 | read dir
447 | if [ -d "$dir" ]
448 | then
449 | echo "Directory exists"
450 | else
451 | `mkdir $dir`
452 | echo "Directory created"
453 | fi
454 | ```
455 |
456 | 使用 eval 编写此程序以提高 bash 脚本编写技能。
457 |
458 | ## 25.读取文件
459 |
460 | Bash 脚本允许用户非常有效地读取文件。下面的示例将展示如何使用 shell 脚本读取文件。首先,创建一个名为 editors.txt 的文件,其中包含以下内容。
461 |
462 | ```
463 | 1. Vim
464 | 2. Emacs
465 | 3. ed
466 | 4. nano
467 | 5. Code
468 | ```
469 |
470 | 此脚本将输出上述 5 行中的每一行。
471 |
472 | ```
473 | #!/bin/bash
474 | file='editors.txt'
475 | while read line; do
476 | echo $line
477 | done < $file
478 | ```
479 |
480 | ## 26.删除文件
481 |
482 | 以下程序将演示如何在 Linux shell 脚本中删除文件。程序将首先要求用户提供文件名作为输入,如果文件名存在,则将其删除。Linux rm 命令在此处执行删除操作。
483 |
484 | ```
485 | #!/bin/bash
486 | echo -n "Enter filename ->"
487 | read name
488 | rm -i $name
489 | ```
490 |
491 | 让我们输入 editors.txt 作为文件名,并在要求确认时按 y。它应该删除该文件。
492 |
493 | ## 27.附加到文件
494 |
495 | 下面的 shell 脚本示例将向您展示如何使用 bash 脚本将数据附加到文件系统上的文件。它向早期的 editors.txt 文件添加了一行。
496 |
497 | ```
498 | #!/bin/bash
499 | echo "Before appending the file"
500 | cat editors.txt
501 | echo "6. NotePad++" >> editors.txt
502 | echo "After appending the file"
503 | cat editors.txt
504 | ```
505 |
506 | 现在您应该注意到,我们直接从 Linux bash 脚本使用日常终端命令。
507 |
508 | ## 28.测试文件存在
509 |
510 | 下一个 shell 脚本示例显示如何检查 bash 程序中文件的存在。
511 |
512 | ```
513 | #!/bin/bash
514 | filename=$1
515 | if [ -f "$filename" ]; then
516 | echo "File exists"
517 | else
518 | echo "File does not exist"
519 | fi
520 | ```
521 |
522 | 我们直接从命令行传递文件名作为参数。
523 |
524 | ## 29.从 Shell 脚本发送邮件
525 |
526 | 从 bash 脚本发送电子邮件非常简单。下面的简单示例将演示一种从 bash 应用程序执行此操作的方法。
527 |
528 | ```
529 | #!/bin/bash
530 | recipient=”admin@example.com”
531 | subject=”Greetings”
532 | message=”Welcome to UbuntuPit”
533 | `mail -s $subject $recipient <<< $message`
534 | ```
535 |
536 | 它将向收件人发送包含给定主题和消息的电子邮件。
537 |
538 | ## 30.解析日期和时间
539 |
540 | 下一个 bash 脚本示例将向您展示如何使用脚本处理日期和时间。同样,Linuxdate 命令用于获取必要的信息,我们的程序执行解析。
541 |
542 | ```
543 | #!/bin/bash
544 | year=`date +%Y`
545 | month=`date +%m`
546 | day=`date +%d`
547 | hour=`date +%H`
548 | minute=`date +%M`
549 | second=`date +%S`
550 | echo `date`
551 | echo "Current Date is: $day-$month-$year"
552 | echo "Current Time is: $hour:$minute:$second"
553 | ```
554 |
555 | 运行此程序以了解其工作原理。此外,尝试从终端运行 date 命令。
556 |
557 | ## 31.sleep 命令
558 |
559 | sleep 命令允许 shell 脚本在指令之间暂停。它在许多场景中都很有用,例如执行系统级作业。下一个示例显示了 shell 脚本中的 sleep 命令。
560 |
561 | ```
562 | #!/bin/bash
563 | echo "How long to wait?"
564 | read time
565 | sleep $time
566 | echo "Waited for $time seconds!"
567 | ```
568 |
569 | 该程序暂停最后一条指令的执行,直到 $time 秒,在本例中,用户提供了这一点。
570 |
571 | ## 32.wait 命令
572 |
573 | wait 命令用于暂停 Linux bash 脚本中的系统进程。查看下面的示例,详细了解这在 bash 中的工作方式。
574 |
575 | ```
576 | #!/bin/bash
577 | echo "Testing wait command"
578 | sleep 5 &
579 | pid=$!
580 | kill $pid
581 | wait $pid
582 | echo $pid was terminated.
583 | ```
584 |
585 | ## 33.显示上次更新的文件
586 |
587 | 有时,您可能需要为某些操作查找最后更新的文件。下面的简单程序向我们展示了如何在 bash 中使用 awk 命令执行此操作。它将列出当前工作目录中最近更新或创建的文件。 #!/bin/bash
588 |
589 | ```
590 | ls -lrt | grep ^- | awk 'END{print $NF}'
591 | ```
592 |
593 | 为了简单起见,我们将避免在本示例中描述 awk 的功能。相反,您可以简单地复制此代码来完成任务。
594 |
595 | ## 34.添加批处理扩展
596 |
597 | 下面的示例将对目录中的所有文件应用自定义扩展名。创建一个新目录,并将一些文件放在其中以供演示。我的文件夹共有五个文件,每个文件名为 test,后跟(0-4)。我已将此脚本编程为在文件末尾添加(.UP)。您可以添加所需的任何扩展名。
598 |
599 | ```
600 | #!/bin/bash
601 | dir=$1
602 | for file in `ls $1/*`
603 | do
604 | mv $file $file.UP
605 | done
606 | ```
607 |
608 | 首先,不要从任何常规目录尝试此脚本;相反,请从测试目录运行此命令。此外,您需要提供文件的目录名作为命令行参数。对当前工作目录使用句点(.)。
609 |
610 | ## 35.打印文件或目录的数量
611 |
612 | 下面的 Linuxbash 脚本查找给定目录中存在的文件或文件夹的数量。它使用 Linux find 命令来执行此操作。首先,需要传递目录名以从命令行搜索文件。
613 |
614 | ```
615 | #!/bin/bash
616 |
617 | if [ -d "$@" ]; then
618 | echo "Files found: $(find "$@" -type f | wc -l)"
619 | echo "Folders found: $(find "$@" -type d | wc -l)"
620 | else
621 | echo "[ERROR] Please retry with another folder."
622 | exit 1
623 | fi
624 | ```
625 |
626 | 如果指定的目录不可用或存在权限问题,程序将要求用户重试。
627 |
628 | ## 36.清理日志文件
629 |
630 | 下一个简单的示例演示了在现实生活中使用 shell 脚本的简便方法。该程序只需删除 / var/log 目录中的所有日志文件。您可以更改保存此目录的变量以清理其他日志。
631 |
632 | ```
633 | #!/bin/bash
634 | LOG_DIR=/var/log
635 | cd $LOG_DIR
636 |
637 | cat /dev/null > messages
638 | cat /dev/null > wtmp
639 | echo "Logs cleaned up."
640 | ```
641 |
642 | 请记住以 root 身份运行此 Linuxshell 脚本。
643 |
644 | ## 37.使用 Bash 备份脚本
645 |
646 | Shell 脚本提供了一种强大的方法来备份文件和目录。以下示例将备份过去 24 小时内修改的每个文件或目录。该程序使用 find 命令执行此操作。
647 |
648 | ```
649 | #!/bin/bash
650 |
651 | BACKUPFILE=backup-$(date +%m-%d-%Y)
652 | archive=${1:-$BACKUPFILE}
653 |
654 | find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
655 | echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
656 | exit 0
657 | ```
658 |
659 | 备份过程成功后,它将打印文件和目录的名称。
660 |
661 | ## 38.检查你是否是 root 用户
662 |
663 | 下面的示例演示了通过 Linux bash 脚本快速确定用户是否为 root 用户的方法。
664 |
665 | ```
666 | #!/bin/bash
667 | ROOT_UID=0
668 |
669 | if [ "$UID" -eq "$ROOT_UID" ]
670 | then
671 | echo "You are root."
672 | else
673 | echo "You are not root"
674 | fi
675 | exit 0
676 | ```
677 |
678 | 此脚本的输出取决于运行它的用户。它将根据 $UID 匹配根用户。
679 |
680 | ## 39.从文件中删除重复行
681 |
682 | 文件处理需要相当长的时间,并在许多方面阻碍了管理员的工作效率。例如,在文件中搜索重复项可能会成为一项艰巨的任务。幸运的是,您可以使用一个简短的 shell 脚本来完成此操作。
683 |
684 | ```
685 | #! /bin/sh
686 |
687 | echo -n "Enter Filename-> "
688 | read filename
689 | if [ -f "$filename" ]; then
690 | sort $filename | uniq | tee sorted.txt
691 | else
692 | echo "No $filename in $pwd...try again"
693 | fi
694 | exit 0
695 | ```
696 |
697 | 上面的脚本逐行遍历文件并删除所有重复的行。然后,它将新内容放入新文件,并保持原始文件的完整性。
698 |
699 | ## 40.系统维护
700 |
701 | 我经常使用一个小的 Linuxshell 脚本来升级我的系统,而不是手动升级。下面的简单 shell 脚本将向您展示如何做到这一点。
702 |
703 | ```
704 | #!/bin/bash
705 |
706 | echo -e "\n$(date "+%d-%m-%Y --- %T") --- Starting work\n"
707 |
708 | apt-get update
709 | apt-get -y upgrade
710 |
711 | apt-get -y autoremove
712 | apt-get autoclean
713 |
714 | echo -e "\n$(date "+%T") \t Script Terminated"
715 | ```
716 |
717 | 该脚本还处理不再需要的旧包。您需要使用 sudo 运行此脚本,否则它将无法正常工作。
718 |
--------------------------------------------------------------------------------
/决战Linux到精通4.md:
--------------------------------------------------------------------------------
1 | # vim全套笔记
2 | ## VIM快速复习
3 | ### 什么是 vim?
4 | Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。vim 的官方网站 (http://www.vim.org)
5 |
6 | vim 键盘图:
7 |
8 | 
9 |
10 |
11 | 基本上vi可以分为三种状态:
12 |
13 | - 命令模式(command mode)
14 | - 插入模式(Insert mode)
15 | - 底行模式(last line mode)
16 |
17 | ## 按:冒号即可进入last line mode
18 |
19 | ```txt
20 | :set nu 列出行号
21 | :set nonu 取消行号
22 | :#7 跳到文件中的第7行
23 | /keyword 查找字符 按n向下
24 | ?keyword 查找字符 按N向下
25 | :n1,n2/word1/word2/gc 替换指定范围单词,c表示提示
26 | :w 保存文件
27 | :w filename 以指定的文件名另存
28 | :n1,n2 w [filename] 将 n1 到 n2行另存
29 | :r [filename] 读入另一个文件加到光标所在行后面
30 | :! ls /home 在vi当中察看ls输出信息!
31 | :q离开vi
32 | :wq 和 :ZZ 和 :x 保存并退出vi
33 | !强制执行
34 | :% s/^/#/g 来在全部内容的行首添加 # 号注释
35 | :1,10 s/^/#/g 在1~10 行首添加 # 号注释
36 | ```
37 |
38 | ## 从command mode进入Insert mode
39 | 按i在当前位置编辑
40 |
41 | 按a在当前位置的下一个字符编辑
42 |
43 | 按o插入新行,从行首开始编辑
44 |
45 | 按R(Replace mode):R会一直取代光标所在的文字,直到按下 ESC为止;(常用)
46 |
47 | ## 按ESC键退回command mode
48 | h←j↓k↑l→前面加数字移动指定的行数或字符数
49 |
50 | 1、翻页bu上下整页,ud上下半页
51 |
52 | ```txt
53 | ctrl+b:上移一页。
54 | ctrl+f:下移一页。
55 | ctrl+u:上移半页。
56 | ctrl+d:下移半页。
57 | ```
58 |
59 | 2、行定位
60 |
61 | ```txt
62 | 7gg或7G:定位第7行首字符。(可能只在Vim中有效)
63 | G:移动到文章的最后。
64 | 7H:当前屏幕的第7行行首
65 | M:当前屏幕中间行的行首
66 | 7L:当前屏幕的倒数第7行行首
67 | ```
68 |
69 | 3、当前行定位
70 |
71 | ```txt
72 | $:移动到光标所在行的“行尾”。
73 | 0或^:移动到光标所在行的“行首”
74 | w:光标跳到下个单词的开头
75 | e:光标跳到下个单词的字尾
76 | b:光标回到上个单词的开头
77 | ```
78 |
79 | 4、编辑
80 |
81 | ```txt
82 | x:剪切当前字符
83 | 7x:剪切从当前位置起7个字符
84 | 大写的X,表示从前面一个字符开始往前计算
85 | dd:剪切光标所在行。
86 | 7dd:从光标所在行开始剪切7行
87 | d7G 删除光标所在到第7行的所有数据
88 | yw:复制当前单词
89 | 7yw:复制从当前位置起7个单词
90 | yy:复制当前行
91 | 6yy:从当前行起向下复制6行
92 | y7G 复制游标所在列到第7列的所有数据
93 | p:粘贴
94 | u:撤销
95 | ctrl+r:取消撤销
96 | cw:删除当前单词(从光标位置开始计算),并进入插入模式
97 | c7w:删除7个单词并进入插入模式
98 | ```
99 |
100 | ## 多行编辑,vim支持,vi不支持
101 | 按ctrl+V进入块模式,上下键选中快,按大写G选择到末尾,上下左右键移动选择位置
102 |
103 | 按大写I进去编辑模式,输入要插入的字符,编辑完成按ESC退出
104 |
105 | 选中要替换的字符后,按c键全部会删除,然后输入要插入的字符,编辑完成按ESC退出
106 |
107 | 选中要替删除的字符后,按delete键,则会全部删除
108 |
109 | 按shift+V可进入行模式,对指定行操作
110 |
111 |
112 | ## vim练习
113 | 1、创建目录/tmp/test,将/etc/man.config复制到该目录下
114 |
115 | ```txt
116 | # mkdir -p /tmp/test
117 |
118 | # cp /etc/man.config /tmp/test/
119 |
120 | # cd /tmp/test/
121 | ```
122 |
123 | 2、用vim编辑man.config文件:
124 |
125 | ```txt
126 | vim man.config
127 | ```
128 |
129 | 3、设置显示行号; 移动到第58行,向右移动40个字符,查看双引号内的是什么目录;
130 |
131 | ```txt
132 | :set nu
133 | 58G 或58gg
134 | 40-> 或40空格 目录为:/dir/bin/foo
135 | ```
136 |
137 | 4、移动到第一行,并向下查找“bzip2”这个字符串,它在第几行;
138 |
139 | ```txt
140 | 移动到最后一行,并向上查找该字符串;
141 | gg 或1G
142 | /bzip 137行 ?bzip2
143 | ```
144 |
145 | 5、将50行到100行之间的man更改为MAN,并且 逐个挑选 是否需要修改;
146 |
147 | ```txt
148 | 若在挑选过程中一直按y,结果会在最后一行出现改变了几个man?
149 | :50,100s/man/MAN/gc 25次替换
150 | ```
151 |
152 | 6、修改完后,突然反悔了,要全部复原,有哪些方法?
153 |
154 | ```txt
155 | 一直按u键
156 | 或者
157 | :q!强制不保存退出后,再重新打开该文件
158 | ```
159 |
160 | 7、复制65到73这9行的内容(含有MANPATH_MAP),并且粘贴到最后一行之后;
161 |
162 | ```txt
163 | 65gg或65G到该行后,9yy,G 移动到最后一行,p粘贴
164 | ```
165 |
166 | 8、21行到42行之间开头为#符号的批注数据不要了,如何删除;
167 |
168 | ```txt
169 | 21G到该行 22dd
170 | ```
171 |
172 | 9、将这个文件另存为man.test.config的文件
173 |
174 | ```txt
175 | :w man.test.config
176 | ```
177 |
178 | 10、到第27行,并且删除15个字符,结果出现的第一个字符是什么?
179 |
180 | ```txt
181 | 27gg 后15x
182 | ```
183 |
184 | 11、在第一行新增一行,在该行内输入“I am a student ”
185 |
186 | ```txt
187 | gg到第一行 O输入即可 说明:o是在当前行之后插入一行,O是在当前行之前插入一行
188 | ```
189 |
190 | 12、保存并退出
191 |
192 | ```txt
193 | :wq
194 | ```
195 |
196 |
197 | ## vi/vim的三种模式
198 | vi/vim主要分为三种模式,分别是**命令模式(Command mode),输入模式(Insert mode)和底线命令模式(Last line mode)。**
199 |
200 | 
201 |
202 | 这三种模式的作用分别是:
203 |
204 | ### 命令模式
205 | 用户刚刚启动 vi/vim,便进入了命令模式。 任何时候,不管用户处于何种模式,只要按一下ESC键,即可使Vi进入命令模式;
206 |
207 | 此状态下敲击键盘动作会被Vim识别为命令,输入: 可切换到**底线命令模式**,以在最底一行输入命令。
208 |
209 | 若想要编辑文本:启动Vim,进入了命令模式,按下i,切换到输入模式。
210 |
211 | ### 输入模式
212 | 在命令模式下输入插入命令i、附加命令a 、打开命令o、修改命令c、取代命令r或替换命令s都可以进入文本输入模式。在该模式下,用户输入的任何字符都被Vi当做文件内容保存起来,并将其显示在屏幕上。在文本输入过程中,若想回到命令模式下,按键ESC即可。
213 |
214 | ### 底行模式
215 | 在命令模式下按下:(英文冒号)就进入了底行命令模式。
216 |
217 | 底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。
218 |
219 | 在底线命令模式中,基本的命令有(已经省略了冒号):
220 |
221 | - q 退出程序
222 | - w 保存文件
223 |
224 | 按ESC键可随时退出底线命令模式。
225 |
226 | # vim基础操作
227 | ## 进入输入模式(Insert mode)
228 |
229 | 
230 |
231 | i: 插入光标前一个字符
232 |
233 | I: 插入行首
234 |
235 | a: 插入光标后一个字符
236 |
237 | A: 插入行未
238 |
239 | o: 向下新开一行,插入行首
240 |
241 | O: 向上新开一行,插入行首
242 |
243 |
244 | 在进入输入模式后, vi 画面的左下角处会出现『–INSERT–』的字样
245 |
246 | ## 进入替换模式(Replace mode)
247 | - r : 只会取代光标所在的那一个字符一次
248 | - R: 会一直取代光标所在的文字,直到按下ESC为止
249 |
250 | 在进入输入模式后, vi 画面的左下角处会出现『–REPLACE–』的字样
251 |
252 | ## 命令模式下常用命令
253 | ### 移动光标
254 |
255 | 
256 |
257 |
258 | ### 删除操作
259 |
260 | 
261 |
262 | ### 撤销&复原&重复
263 |
264 | 
265 |
266 | ### 复制&粘贴
267 |
268 | 
269 |
270 |
271 | ### 合成行
272 | - J: 将光标所在行与下一行的数据结合成同一行
273 |
274 | ### 搜索
275 |
276 | 
277 |
278 | ### 替换
279 |
280 | 
281 |
282 |
283 | ## 底行命令模式的常用操作
284 |
285 | 
286 |
287 |
288 | 示例:
289 |
290 | ```txt
291 | 将当前路径插入到光标的下一行
292 | :r!pwd
293 | ```
294 |
295 | ## 可视模式
296 | v 进入字符可视化模式: 文本选择是以字符为单位的。
297 |
298 | V 进入行可视化模式: 文本选择是以行为单位的。
299 |
300 | Ctrl+v 进入块可视化模式 : 选择一个矩形内的文本。
301 |
302 | 可视模式下可进行如下操作:
303 |
304 | 
305 |
306 |
307 | 可视模式下,选中的区域是由两个端点来界定的(一个在左上角,一个在右下角),在默认情况下只可以控制右下角的端点,而使用o按键则可以在左上角和右下角之间切换控制端点。
308 |
309 | ## Linux系统启动过程
310 | Linux系统的启动过程可以分为5个阶段:
311 |
312 | - 内核的引导。
313 | - 运行 init。
314 | - 系统初始化。
315 | - 建立终端 。
316 | - 用户登录系统。
317 |
318 | ## 加载内核
319 | 当计算机打开电源后,首先是BIOS开机自检,按照BIOS中设置的启动设备(通常是硬盘)来启动。
320 |
321 | 操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。
322 |
323 | 
324 |
325 |
326 |
327 | ## 启动初始化进程init
328 | 内核文件加载以后,就开始运行第一个程序 /sbin/init,它的作用是初始化系统环境。
329 |
330 | init程序首先是需要读取配置文件/etc/inittab。
331 |
332 | 
333 |
334 |
335 | 
336 |
337 |
338 | 由于init是第一个运行的程序,它的进程编号(pid)就是1。其他所有进程都从它衍生,都是它的子进程。
339 |
340 | ## 确定运行级别
341 | 许多程序需要开机启动。它们在Windows叫做"服务"(service),在Linux就叫做"守护进程"(daemon)。
342 |
343 | init进程的一大任务,就是去运行这些开机启动的程序。
344 |
345 | 但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。
346 |
347 | Linux允许为不同的场合,分配不同的开机启动程序,这就叫做"运行级别"(runlevel)。也就是说,启动时根据"运行级别",确定要运行哪些程序。
348 |
349 | 
350 |
351 | Linux系统有7个运行级别(runlevel):
352 |
353 | - 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
354 | - 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
355 | - 运行级别2:多用户状态(没有NFS)
356 | - 运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
357 | - 运行级别4:系统未使用,保留
358 | - 运行级别5:X11控制台,登陆后进入图形GUI模式
359 | - 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动
360 |
361 | 可以使用运行级别执行关机或重启:
362 |
363 | ```txt
364 | init 0 关机
365 | init 6 重启
366 | ```
367 |
368 | ## 加载开机启动程序
369 | 在init的配置文件中有这么一行: si::sysinit:/etc/rc.d/rc.sysinit它调用执行了/etc/rc.d/rc.sysinit,而rc.sysinit是一个bash shell的脚本,它主要是完成一些系统初始化的工作,rc.sysinit是每一个运行级别都要首先运行的重要脚本。
370 |
371 | 它主要完成的工作有:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。
372 |
373 | ```txt
374 | l5:5:wait:/etc/rc.d/rc 5
375 | ```
376 |
377 | 这一行表示以5为参数运行/etc/rc.d/rc,/etc/rc.d/rc是一个Shell脚本,它接受5作为参数,去执行/etc/rc.d/rc5.d/目录下的所有的rc启动脚本,/etc/rc.d/rc5.d/目录中的这些启动脚本实际上都是一些连接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。
378 |
379 | 而这些rc启动脚本有着类似的用法,它们一般能接受start、stop、restart、status等参数。
380 |
381 | /etc/rc.d/rc5.d/中的rc启动脚本通常是K或S开头的连接文件,对于以 S 开头的启动脚本,将以start参数来运行。
382 |
383 | 而如果发现存在相应的脚本也存在K打头的连接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。
384 |
385 | 这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。
386 |
387 | 至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig或setup中的"System Services"来自行设定。
388 |
389 | 
390 |
391 |
392 | ## 用户登录
393 | 一般来说,用户的登录方式有三种:
394 |
395 | - (1)命令行登录
396 | - (2)ssh登录
397 | - (3)图形界面登录
398 |
399 | 
400 |
401 |
402 | 对于运行级别为5的图形方式用户来说,他们的登录是通过一个图形化的登录界面。登录成功后可以直接进入 KDE、Gnome 等窗口管理器。
403 |
404 | 而本文主要讲的还是文本方式登录的情况:当我们看到mingetty的登录界面时,我们就可以输入用户名和密码来登录系统了。
405 |
406 | Linux 的账号验证程序是login,login会接收mingetty传来的用户名作为用户名参数。
407 |
408 | 然后login会对用户名进行分析:如果用户名不是root,且存在 /etc/nologin 文件,login 将输出 nologin 文件的内容,然后退出。
409 |
410 | 这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许 root 用户登录,如果不存在这个文件,则root用户可以在任何终端上登录。
411 |
412 | /etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。
413 |
414 | ## 图形模式与文字模式的切换方式
415 | Linux预设提供了六个命令窗口终端机让我们来登录。
416 |
417 | 默认我们登录的就是第一个窗口,也就是tty1,这个六个窗口分别为tty1,tty2 … tty6,你可以按下Ctrl + Alt + F1 ~ F6 来切换它们。
418 |
419 | 如果你安装了图形界面,默认情况下是进入图形界面的,此时你就可以按Ctrl + Alt + F1 ~ F6来进入其中一个命令窗口界面。
420 |
421 | 当你进入命令窗口界面后再返回图形界面只要按下Ctrl + Alt + F7 就回来了。
422 |
423 | 如果你用的vmware 虚拟机,命令窗口切换的快捷键为 Alt + Space + F1~F6. 如果你在图形界面下请按Alt + Shift + Ctrl + F1~F6 切换至命令窗口。
424 |
425 | ## login shell
426 |
427 | 
428 |
429 |
430 | shell,简单说就是命令行界面,让用户可以直接与操作系统对话。用户登录时打开的shell,就叫做login shell。
431 |
432 | (1)命令行登录:首先读入 /etc/profile,这是对所有用户都有效的配置;然后依次寻找下面三个文件,这是针对当前用户的配置。
433 |
434 | ```txt
435 | ~/.bash_profile
436 | ~/.bash_login
437 | ~/.profile
438 | ```
439 |
440 | 需要注意的是,这三个文件只要有一个存在,就不再读入后面的文件了。比如,要是 ~/.bash_profile 存在,就不会再读入后面两个文件了。
441 |
442 | (2)ssh登录:与第一种情况完全相同。
443 |
444 | (3)图形界面登录:只加载 /etc/profile 和 /.profile。也就是说,/.bash_profile 不管有没有,都不会运行。
445 |
446 | ## Linux关机
447 |
448 | ```txt
449 | sync 将数据由内存同步到硬盘中。
450 |
451 | shutdown 关机指令,你可以man shutdown 来看一下帮助文档。例如你可以运行如下命令关机:
452 | shutdown –h 10 'This server will shutdown after 10 mins' 计算机将在10分钟后关机,并且显示信息在登陆用户的当前屏幕中。
453 | shutdown –h now 立马关机
454 | shutdown –h 20:25 系统会在今天20:25关机
455 | shutdown –h +10 十分钟后关机
456 | shutdown –r now 系统立马重启
457 | shutdown –r +10 系统十分钟后重启
458 | reboot 就是重启,等同于 shutdown –r now
459 | halt 关闭系统,等同于shutdown –h now 和 poweroff
460 | ```
461 |
462 | 最后总结一下,不管是重启系统还是关闭系统,首先要运行**sync**命令,把内存中的数据写到磁盘中。
463 |
464 | 关机的命令有 **shutdown –h now halt poweroff 和 init 0** , 重启系统的命令有 **shutdown –r now reboot init 6。**
465 |
466 | # 计算机启动的流程
467 |
468 | 
469 |
470 |
471 | boot是bootstrap(鞋带)的缩写,它来自一句谚语:
472 |
473 | 
474 |
475 |
476 | 字面意思是"拽着鞋带把自己拉起来",这当然是不可能的事情。最早的时候,工程师们用它来比喻,计算机启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序!
477 |
478 | 早期真的是这样,必须想尽各种办法,把一小段程序装进内存,然后计算机才能正常运行。所以,工程师们把这个过程叫做"拉鞋带",久而久之就简称为boot了。
479 |
480 | 计算机的整个启动过程分成四个阶段。
481 |
482 | ## 第一阶段:BIOS
483 | 上个世纪70年代初,“只读内存”(read-only memory,缩写为ROM)发明,开机程序被刷入ROM芯片,计算机通电后,第一件事就是读取它。
484 |
485 | BIOS全称是Basic Input/Output System,即基本输入输出系统,即下图芯片里的程序。
486 |
487 | 
488 |
489 | ### 硬件自检
490 |
491 | BIOS程序首先检查,计算机硬件能否满足运行的基本条件,这叫做"硬件自检"(Power-On Self-Test),缩写为POST。
492 |
493 | 如果硬件出现问题,主板会发出不同含义的蜂鸣,启动中止。如果没有问题,屏幕就会显示出CPU、内存、硬盘等信息。
494 |
495 | 
496 |
497 | ### 启动顺序
498 |
499 | 硬件自检完成后,BIOS把控制权转交给下一阶段的启动程序。
500 |
501 | 下一阶段的启动程序根据BIOS设置项Boot Sequence(启动顺序)决定,排在前面的设备就是优先转交控制权的设备。
502 |
503 | 
504 |
505 | ## 第二阶段: 主引加粗样式导记录
506 | BIOS按照"启动顺序",把控制权转交给排在第一位的储存设备。
507 |
508 | 这时,计算机读取该设备的第一个扇区,也就是读取最前面的512个字节。如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给"启动顺序"中的下一个设备。
509 |
510 | 这最前面的512个字节,就叫做"主引导记录"(Master boot record,缩写为MBR)。
511 |
512 | ### 主引导记录组成
513 |
514 | 主引导记录由三个部分组成:
515 |
516 | 
517 |
518 | 其中,第二部分"分区表"的作用,是将硬盘分成若干个区。
519 |
520 | ### 分区表
521 |
522 | 硬盘分区有很多好处。每个分区可以安装不同的操作系统,"主引导记录"因此必须知道将控制权转交给哪个区。
523 |
524 | 分区表的长度只有64个字节,里面又分成四项,每项16个字节。所以,一个硬盘最多只能分四个一级分区,又叫做"主分区"。
525 |
526 | 每个主分区的16个字节,由6个部分组成:
527 |
528 | 
529 |
530 | 最后的四个字节(“主分区的扇区总数”),决定了这个主分区的长度。也就是说,一个主分区的扇区总数最多不超过2的32次方。
531 |
532 | 如果每个扇区为512个字节,就意味着单个分区最大不超过2TB。再考虑到扇区的逻辑地址也是32位,所以单个硬盘可利用的空间最大也不超过2TB。如果想使用更大的硬盘,只有2个方法:一是提高每个扇区的字节数,二是增加扇区总数。
533 |
534 | ## 第三阶段:硬盘启动
535 | 这时,计算机的控制权就要转交给硬盘的某个分区了,这里又分成三种情况。
536 |
537 | ### 情况A:卷引导记录
538 |
539 | 上一节提到,四个主分区里面,只有一个是激活的。计算机会读取激活分区的第一个扇区,叫做"卷引导记录"(Volume boot record,缩写为VBR)。
540 |
541 | "卷引导记录"的主要作用是,告诉计算机,操作系统在这个分区里的位置。然后,计算机就会加载操作系统了。
542 |
543 | ### 情况B:扩展分区和逻辑分区
544 |
545 | 随着硬盘越来越大,四个主分区已经不够了,需要更多的分区。但是,分区表只有四项,因此规定有且仅有一个区可以被定义成"扩展分区"(Extended partition)。
546 |
547 | 所谓"扩展分区",就是指这个区里面又分成多个区。这种分区里面的分区,就叫做"逻辑分区"(logical partition)。
548 |
549 | 计算机先读取扩展分区的第一个扇区,叫做"扩展引导记录"(Extended boot record,缩写为EBR)。它里面也包含一张64字节的分区表,但是最多只有两项(也就是两个逻辑分区)。
550 |
551 | 计算机接着读取第二个逻辑分区的第一个扇区,再从里面的分区表中找到第三个逻辑分区的位置,以此类推,直到某个逻辑分区的分区表只包含它自身为止(即只有一个分区项)。因此,扩展分区可以包含无数个逻辑分区。
552 |
553 | 但是,似乎很少通过这种方式启动操作系统。如果操作系统确实安装在扩展分区,一般采用下一种方式启动。
554 |
555 | ### 情况C:启动管理器
556 |
557 | 在这种情况下,计算机读取"主引导记录"前面446字节的机器码之后,不再把控制权转交给某一个分区,而是运行事先安装的"启动管理器"(boot loader),由用户选择启动哪一个操作系统。
558 |
559 | Linux环境中的启动管理器例如Grub。
560 |
561 | 
562 |
563 | ## 第四阶段:操作系统
564 | 控制权转交给操作系统后,操作系统的内核首先被载入内存。
565 |
566 | 以Linux系统为例,先载入/boot目录下面的kernel。内核加载成功后,第一个运行的程序是/sbin/init。它根据配置文件(Debian系统是/etc/initab)产生init进程。这是Linux启动后的第一个进程,pid进程编号为1,其他进程都是它的后代。
567 |
568 | 然后,init线程加载系统的各个模块,比如窗口程序和网络程序,直至执行/bin/login程序,跳出登录界面,等待用户输入用户名和密码。
569 |
570 | 至此,全部启动过程完成。
571 |
572 | ## 单用户模式修改Centos系统root密码
573 | 步骤如下:
574 |
575 | 重启linux系统
576 |
577 | 
578 |
579 | 3 秒之内要按一下回车,出现如下界面
580 |
581 | 
582 |
583 | 按向下方向键移动到第二行,按"e"进入编辑模式
584 |
585 | 
586 |
587 | 在 第二行最后边输入 single,用空格与前面内容隔开
588 |
589 | 
590 |
591 | 回车
592 |
593 | 
594 |
595 | 最后按"b"启动,启动后就进入了单用户模式了
596 |
597 | 
598 |
599 | 进入到单用户模式后,就可以使用passwd命令任意更改root密码了:
600 |
601 | 
602 |
603 | ## 救援模式修改Ubuntu系统root密码
604 | 重启,按住shift键,出现如下界面,选中如下选项
605 |
606 | 
607 |
608 | 按回车键进入如下界面,然后选中最新的recovery mode选项
609 |
610 | 
611 |
612 | 按e进入如下界面,找到图中红色框的recovery nomodeset并将其删掉,再在这一行的后面输入
613 |
614 | ```txt
615 | quiet splash rw init=/bin/bash
616 | ```
617 |
618 | 
619 |
620 | 
621 |
622 | 接着按F10或者Ctrl+x 后出现如下界面,在命令行内输入passwd后进行修改密码即可
623 |
624 | 
625 |
626 | 修改完之后重启系统。
627 |
628 | # 虚拟机
629 | ## 三种网络模式
630 | ### 桥接
631 |
632 | 在网络网卡上安装了一个桥接协议,让这块网卡处于混杂模式,可以同时连接多个网络的做法。
633 |
634 | 桥接下,类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样查在这个交换机当中,所以所有桥接下网卡与网卡都是交换模式的,相互可以访问而不干扰。
635 |
636 | 
637 |
638 | ### Host-only(仅与主机通信)
639 |
640 | 虚拟机使用VMnet1网卡与主机单独组网,主机对于虚拟机相当于路由器
641 |
642 | 
643 |
644 | ### NAT
645 |
646 | 虚拟机使用VMnet8网卡与主机单独组网,主机对于虚拟机相当于路由器,VMnet8网卡通过NAT地址转换协议与物理机网卡通信
647 |
648 | 
649 |
650 | 
651 |
652 | ## 常见问题
653 | ### 修改静态地址后发现无法ping外网
654 |
655 | ```txt
656 | 需要设置网关
657 | route add default gw 192.168.33.1
658 | 添加nameserver
659 | vi /etc/resolv.conf
660 | nameserver 192.168.33.1
661 | ```
662 |
663 | ### 虚拟机克隆后eth0消失
664 |
665 | ```txt
666 | 直接修改 /etc/sysconfig/network-script/ifcfg-eth0
667 | 删掉UUID HWADDR
668 | 配置静态地址
669 | 然后:
670 | rm -rf /etc/udev/rules.d/70-persistent-net.rules
671 | 然后 reboot
672 | ```
673 |
--------------------------------------------------------------------------------