后面也会持续更新,学到新东西会在其中补充。
建议按顺序食用,欢迎批评或者交流!
缺什么东西欢迎评论!我都会及时修改的!
在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频
王晓春老师的个人空间-王晓春老师个人主页-哔哩哔哩视频
标准输入和输出
程序(应用程序):指令+数据
读入数据:Input
输出数据:Output
Linux中一切皆文件,操作输入输出都是所谓的文件,文件表现为每打开一个文件,系统会分配一个数字,这个数字代表一个文件,这个数字叫做文件描述符(file descriptor)
每一个程序由于通常都是需要处理数据的,输入,输出,错误三种信息
一切皆文件,所以输入输出错误对应的都有一个文件描述符。
在Linux中是固定的一个数字 标准输入 0 标准输出 1 标准错误 2
应用程序1-4都有输入,输出,错误
当每打开文件,系统就会分配打开这个文件唯一的文件描述符。
只有三个(0 1 2)打开的文件的文件描述符是固定的分配给当前程序对应的输入0输出1错误2
至于其他文件打开,描述符就是随机的。
通过proc 目录可以观察到这个程序所对应的内存信息
这里是windows中的
定位程序真正位置
ps aux
第二列为pid
1983文件夹里面存放着关于正在运行的tail命令详细命令
程序打开了哪些文件
[root@study fd]# ll
total 0
lrwx------. 1 root root 64 Nov 6 06:57 0 -> /dev/pts/1 标准输入
lrwx------. 1 root root 64 Nov 6 06:57 1 -> /dev/pts/1 标准输出
lrwx------. 1 root root 64 Nov 6 06:56 2 -> /dev/pts/1 标准错误
lr-x------. 1 root root 64 Nov 6 06:57 3 -> /root/anaconda-ks.cfg
0 1 2是用来实现标准输入 标准输出 标准错误三个固定的文件描述符
3 就是正在打开的文件 程序一打开文件 系统自动分配文件描述符 除了0 1 2是固定的
0 1 2是文件描述符本质就是软链接指向的是当前终端窗口
shell的pid
当前窗口也是在一个进程(程序)里面 也就是shell 登录的时候就会在内存中开启一个shell
因为开了三个窗口所以有三个shell
把0 1 2都映射成当前的终端设备终端窗口
输入输出错误 都是通过当前终端窗口来实现输入输出错误,每个窗口有自己的输入输出错误。
ll /proc/$$/fd 就是显示当前shell的文件描述符
tty是显示当前终端窗口
输入输出错误都靠当前终端窗口
stdin 标准输入 stderr 标准错误 stdout 标准输出 self对应当前的进程编号
ll /proc/self -d 显示当前的进程编号
会发现进程编号2172 没有 因为ll程序已经结束了 ll命令执行的时候 瞬间系统分配一个进程编号,ll命令不是持续运行的,运行完就退出了在proc下面就看不见2172。
每个程序运行系统都会分配一个所谓的进程编号,并且对应的有一个固定的三个文件描述符。
输入:默认接受来自终端窗口的输入 输出:默认输出到终端窗口 错误:默认输出到终端窗口
I/O重定向redirect
1> == > | 把STDOUT重定向到文件 1> 1代表标准输出 |
2> | 2 代表标准错误 把标准错误重定向到文件 |
&> | 把所有输出重定向到文件 |
stdout(标准输出)和stderr(标准错误)可以重定向到指定文件,而非默认的当前终端。
将标准输出输出到别的地方
标准输出就是ll等等命令 输出本来是输出到当前终端窗口 但是重定向到其他终端窗口去了
w命令查看终端都在干啥
标准输出重定向普通文件
>很危险
生成空文件
echo > 可以生成空文件吗
echo 运行echo会换行
but 还是推荐cat /dev/null > /data/file.log 来清除大文件
标准错误重定向到其他地方
提示信息是标准输出还是标准错误?
答案是标准错误
既有标准输出又有标准错误
ll /data /err > /data/right.log 2> /data/err.log
ll /data /err &> /data/all.log 比较新的命令把标准输出和标准错误都放到all.log
ls /data /err > /data/all.log 2>&1 == ls /data /err 2> /data/all.log 1>&2 比较老的命令
ls /data /err 2>&1 > /data/all.log 错误的命令
想把命令隐藏又不想生成临时文件
不想覆盖文件可以追加
把两个命令结果重定向到同一个文件中
(ls ; date) > /data/f1.log
{ ls;date;}格式错一点都会报错!
< 标准输入
<代替了终端窗口的手工输入 批量操作减少人工操作
seq的作用
1 + 到 100 实验
抛弃了人工操作
有没有觉得这种操作很麻烦需要一个中间文件来传递数据
为什么不能直接获得数据传入bc呢?我们引入了管道
管道
命令1 | 命令2 | 命令3
命令1输出信息当作命令2的输入信息
命令1 肯定有标准输出才能放到管道前 命令2 肯定是有标准输入才能放在管道后seq -s+ 1 100 | bc
管道文件 p 开头
单行重定向
cat 支持标准输入和标准输出
cat.log文件是否存在 是否有内容?
是有line1 还是 line2 还是 line1 和 line2
相当于本来标准输出就在cat.log文件你只是不断标准输入而已
一回车就输入信息
多行重定向
cat2.log文件是否存在 是否有内容?
因为还未发生重定向操作得把这几行 敲入EOF才能结束 EOF
前面后面没有空格
<< 后面的字母是随机的设置什么都行看个人习惯
使用的较多 单行重定向增加了IO 多行减少了IO次数增加了效率
效率提高了有没有缺点呢?打完数据才能看到还没提交 打半天的数据就可能丢失!有安全风险,提高效率可能会导致数据不安全。如同buffer断电可能会丢失数据但是可以提高效率。
PS2影响多行重定向
tr
-t | 改变了匹配逻辑 |
-d | 删除出现的字母 |
-s | 把连续的字母给压缩成一个 |
-c | 取补集除了此字符其他都删 |
123 改成 abc
-t 改变了匹配逻辑
小写转大写
-d 删除出现的字母
-s把连续的字母给压缩成一个
取补集除了此字符 除了abc都删除了
除了数字字母都删除
tr -dc '[:alnum:]' < /dev/urandom
df 标准输出 到 tr 标准输入
1+...100实验
输出A到Z换行
echo {A..Z}|tr ' ' '\n'
将小写字母转换为大写字母
ls /data /err | tr 'a-z' 'A-Z'
ls /data /err 2>&1 | tr 'a-z' 'A-Z'
ls /data /err |& tr 'a-z' 'A-Z'
通过管道发邮件
ls /data /err |& tr 'a-z' 'A-Z' | mail -s test2 wang
反向打印语句
[root@study ~]# echo "FBI Waring" | rev
gniraW IBF
练习
1 cat /etc/issue | tr 'a-z' 'A-Z' | tee /tmp/issue.out
2 whoami | tr 'a-z' 'A-Z' | tee /tmp/who.out
3 mail -s help root << EOF
I am `whoami` 你好可爱啊!
EOF
4 ls /root | tr '\n' ' '
5 echo {1..100} | tr ' ' + | bc
6 [root@study data]# tr -d '\r' < win.txt > win1.txt
[root@study data]# file win1.txt
win1.txt: ASCII text
7 echo 'xt.,l 1 jr#$!$' | tr -dc '0-9 '
8 echo $PATH | tr ':' '\n'
9 [root@study data]# cat 123.txt
0123456789
[root@study data]# cat 123.txt | tr '0-9' 'a-j'
abcdefghij
10 cat /etc/redhat-release | tr ' ' '\n'
3:
tee
-a | 效果等于>> |
像一个大写的T
既写文件也显示到屏幕上
echo "xiao wang" | tee /data/test.logcat /data/test.log
追加
echo "xiao wang" | tee -a /data/test.logcat /data/test.log
更强大的效果
echo "xiao wang" | tee -a /data/test.log | tr 'a-z' 'A-Z'cat /data/test.log
不用再手工执行cat命令
[root@study ~]# cat .mailrc
set from=1326228718@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=1326228718@qq.com
set smtp-auth-password=yfwnfvezofuiiefj
set smtp-auth=login
set ssl-verify=ignorecat <<EOF | tee .mailrc
登录提示修改
[root@study data]# cat << EOF | tee /etc/motd
> welcome to magedu
> happy new year
> EOF
welcome to magedu
happy new year
管道中的-符号
tar -cvf a.tar /home | tar -xvf a.tar
同一文件就可以用-省去
tar -cvf - /home | tar -xvf -
将交互式改为非交互式(修改密码)
passwd --stdin wang 标准输入
[root@study ~]# echo password | passwd --stdin wang
Changing password for user wang.
passwd: all authentication tokens updated successfully.
[root@study ~]# cat pass.txt | passwd --stdin wang
Changing password for user wang.
passwd: all authentication tokens updated successfully.
[root@study ~]# cat pass.txt | passwd --stdin wang &> /dev/null
windows和Linux格式转换
hexdump -c win.txt
hexdump -C win.txt
hexdump -c linux.txt
hexdump -C linux.txt
\n 是换行 \r 是回车
\NNN 意思是可以输入8进制代替
tr -d '\015' < win.txt > linux.txt 把回车键删除
拆分一下就是
tr -d '\015' < win.txt == x
x > linux.txt
这种方法可能出现问题 一般都是处理文本 把Linux转windows因为一个字符不能转两个
还是用dos2unix
这篇文章详细写了windows格式转换Linux格式
Linux(文件管理 图片+大白话)-CSDN博客
发邮件
yum -y install postfix
systemctl start postfix
ctrl + D 正常退出 ctrl + C强制退出
群发邮件
邮箱报警
yum -y install mailx
rpm -qf /usr/bin/mail
mail
这个文件只能放在家目录
[root@study1 ~]# cat .mailrc
set from=手机号3@163.com 发信人这两地方得一样
set smtp=smtp.163.com 服务器地址
set smtp-auth-user=手机号@163.com 发信人这两地方得一样
set smtp-auth-password=YCihMCSp8QUNCLAX 授权码
set smtp-auth=login
set ssl-verify=ignore
echo "FBI Waring" | mail -s "hi" 手机号@163.com
qq邮箱不知道为什么老报530 Login fail. A secure connection is requiered(such as ssl)
参考文献
1IO重定向技术详解_哔哩哔哩_bilibili
2重定向和管道详解_哔哩哔哩_bilibili
3标准IO重定向和管道实战案例_哔哩哔哩_bilibili
Linux tr命令教程:如何使用tr命令进行字符转换(附案例详解和注意事项)_1.tr -embedding-CSDN博客
总结
所有命令都需要反复敲来实验来记忆,本人基本上是个人理解加参考其他大佬的肯定有很多问题欢迎指正,我会及时修改。