20 Shell Script输入与输出

news2024/10/19 5:42:28

标出输入、标准输出、错误输出

一、程序的基本三个IO流

一)文件描述符

​ 任何程序在Linux系统中都有3个基本的文件描述符

在这里插入图片描述

​ 比如:

​ cd/proc/$$/fd

​ 进入当前shell程序对于内核在文件系统的映射目录中:

[root@localhost ~]# cd /proc/$$/fd
[root@localhost fd]# ll
total 0
lrwx------. 1 root root 64 Oct 14 07:22 0 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 07:22 1 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 07:22 2 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 08:56 255 -> /dev/pts/0

​ 文件描述符的意义:

​ 0:标准输入(stdin):0代表:/dev/stdin文件的IO

​ 1:标准输出(stdout):1代表:/dev/stdout文件的IO

​ 2:错误输出(stderr):2代表:/dev/stderr文件的IO

​ 程序已经写死,linux为我们准备了这些文件描述符,以及一些能够重定向这些文件描述符的操作方法,我们可以修改程序的默认输入/输出位置

二)重定向

​ 重定向不是命令,是bash对关键字识别后应用文件描述符指向的操作

​ 输出重定向

​ 输入重定向来自文件

​ 输入重定向来自字符串

​ 基于文件描述符操作的重定向

二、输出重定向

​ 重定向不是命令,是bash对关键字识别后应用文件描述符指向的操作

​ 格式:

​ command [1-n] > file或文件操作符或设备

​ 上面命令意思是:将一条命令执行结果(标准输出,或者错误输出,本来都要打印到屏幕上面的)重定向其它输出设备(文件,打开文件操作符,或打印机等等)1,2分别是标准输出,错误输出。

ls -l /:命令默认将执行结果输出到屏幕

​ ls -l / 1> ls.txt

​ 1:代表的是ls命令的文件描述符,表示的是ls的标准输出

​ >:代表的输出重定向,这里重定向到后面的ls.txt文件中

​ 文件描述符与重定向操作符之间不能出现空格,因为bash会用空白符切割字符串,有空格会认为1是一个文件

# 创建ls.txt文件
[root@localhost ~]# touch ls.txt

# 将文件的标准输出,输入到ls.txt文件中
[root@localhost ~]# ls -l / 1> ls.txt

# 查看文件内容
[root@localhost ~]# cat ls.txt
total 28
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
drwxr-xr-x.  20 root root 3240 Oct 14 07:20 dev
-rw-r--r--.   1 root root  400 Jul 22 20:21 dump.rdb
drwxr-xr-x.  85 root root 8192 Oct 14 07:22 etc
drwxr-xr-x.   5 root root   39 Aug 20 04:24 home
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 lib -> usr/lib
……

​ 再次执行ls -l /root 1> ls.txt命令,会发现文件ls.txt中只有/root的内容

​ 因为:>操作符是覆盖重定向

# 覆盖重定向
[root@localhost ~]# ls -l /root 1> ls.txt

# 查看文件内容
[root@localhost ~]# cat ls.txt
total 0
-rw-r--r--. 1 root root   0 Oct 14 09:21 ls.txt

​ >>:是追加重定向操作符

​ 这样就能追加内容

# 追加重定向
[root@localhost ~]# ls -l /root 1>> ls.txt

# 查看文件内容
[root@localhost ~]# cat ls.txt            
total 0
-rw-r--r--. 1 root root 0 Oct 14 09:22 ls.txt
total 4
-rw-r--r--. 1 root root 54 Oct 14 09:22 ls.txt

​ 注意:文件描述符在这种重定向到文件的操作中可以省略

# 省略文件描述符
[root@localhost ~]# ls -l /root > ls.txt

# 省略文件描述符
[root@localhost ~]# ls -l /root >> ls.txt

ls -l / /god命令让ls显示根目录/和/god目录的内容,但是我们的系统的/目录下没有god目录

​ 输出的结果中包含可以显示内容的/的输出,和一个没有找到/god的报错输出

​ 这个报错输出就是程序的错误输出

[root@localhost ~]# ls -l / /god
ls: cannot access /god: No such file or directory
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
……

​ 如果想将错误输出重定向:

# 创建lserr.txt
[root@localhost ~]# touch lserr.txt

# 将错误输出,输入到lserr.txt
[root@localhost ~]# ls -l / /god 2> lserr.txt
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
drwxr-xr-x.  20 root root 3240 Oct 14 07:20 dev
-rw-r--r--.   1 root root  400 Jul 22 20:21 dump.rdb
drwxr-xr-x.  85 root root 8192 Oct 14 07:22 etc
……

# 查看保存内容
[root@localhost ~]# cat lserr.txt
ls: cannot access /god: No such file or directory

​ 追加的方式:

# 将保存内容,追加到lserr.txt
[root@localhost ~]# ls -l / /god 2>> lserr.txt
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
drwxr-xr-x.  20 root root 3240 Oct 14 07:20 dev
……

# 查看文件内容
[root@localhost ~]# cat lserr.txt
ls: cannot access /god: No such file or directory
ls: cannot access /god: No such file or directory

​ 分别将输出重定向到不同的文件中

# 将输出结果分别覆盖输入到文件中
[root@localhost ~]# ls -l / /god 1> ls.txt 2> lserr.txt

# 标准输出文件
[root@localhost ~]# cat ls.txt                         
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
……

# 错误输出文件
[root@localhost ~]# cat lserr.txt                      
ls: cannot access /god: No such file or directory

​ 如果向重定向到同一个文件,这里会被覆盖,要用追加的方式:

# 将输出结果分别追加输入到文件中
[root@localhost ~]# ls -l / /god 1>> ls.txt 2>> lserr.txt

# 标准输出文件
[root@localhost ~]# cat ls.txt                           
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
drwxr-xr-x.  20 root root 3240 Oct 14 07:20 dev
……

# 错误输出文件
[root@localhost ~]# cat lserr.txt
ls: cannot access /god: No such file or directory
ls: cannot access /god: No such file or directory
ls: cannot access /god: No such file or directory

​ 也可以用文件描述符重定向到文件描述符

​ 语法: 文件描述符>& 文件描述符

​ 注意:>&前面必须有文件描述符,且不能有空格,后面的数字才能被认为是文件描述符

# 创建lsall
[root@localhost ~]# touch lsall.txt

# 将所有输出结果,输入到lsall文件(方式1)
[root@localhost ~]# ls -l / /god > lsall.txt 2>&1

# 查看内容
[root@localhost ~]# cat lsall.txt
ls: cannot access /god: No such file or directory
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
……

# 将所有输出结果,输入到lsall文件(方式2)
[root@localhost ~]# ls -l / /god &> lsall.txt 

# 查看内容,结果相同
[root@localhost ~]# cat lsall.txt
ls: cannot access /god: No such file or directory
/:
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
drwxr-xr-x.   3 root root   18 Jul 20 21:45 data
……

三、输入重定向

一)来自文件

​ read命令:

# 获取键盘输入
[root@localhost ~]# read var01
abc

# 查看
[root@localhost ~]# echo $var01
abc

​ read命令开启输入流,遇到换行符结束输入,将输入流的内容赋值给变量

[root@localhost ~]# read var 0< /etc/profile

# 查看变量
[root@localhost ~]# echo $var
# /etc/profile

​ 我们修改了read命令的输入源,使其来自文件,但是因为read命令的自身特征,读取第一行后遇到换行符,所以,只将第一行内容保存到变量var中

​ 0<:0是标准输入的文件描述符,<是输入重定向操作符,后面要接文件

二)来自字符串

​ 将字符串放入输入流

# 输入hello world
[root@localhost ~]# read var03 <<< "hello world"

# 查看输出内容
[root@localhost ~]# echo $var03                 
hello world

​ <<<:是输入重定向操作符,将命令的输入源重定向为操作符后面的字符串

[root@localhost ~]# vi test.sh
#!/bin/bash
echo "----------"
cat <<EOF
hello world
hello linux
EOF
echo "---------"

[root@localhost ~]# bash test.sh   
----------
hello world
hello linux
---------

​ <<:是重定向操作符,其后紧随的字符串为边界字符串,与结束的边界字符串组合,将其中的内容放入命令的标准输入中

​ 如果将cat换成read,依然会受到换行符的影响

三)基于文件描述符操作的重定向

​ exec命令:

​ Replace the shell with the given command.

​ bash的内部命令

[root@localhost ~]# exec ls -l /
total 24
lrwxrwxrwx.   1 root root    7 Apr 17 04:26 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 May 15 23:07 boot
……
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(192.168.100.160) at 21:52:39.


​ 可以看到ls命令成功执行了,但是我们的xshell也断开了链接

​ 因为exec调用内核系统调用将ls命令的指令替换当前bash的进程,指令接收后退出进程,所以我们的bash链接就中断了

​ 这里我们可以调用exec命令,而不给出替换命令,只附加重定向操作符

​ 这样我们就可以实现对当前bash开启文件描述符

​ 这里我们可以调用exec命令,而不给出替换命令,只附加重定向操作符

​ 这样我们就可以实现对当前bash开启文件描述符

[root@localhost ~]# exec 8< /etc/profile

# 输入文件描述符8
[root@localhost ~]# ls -l /proc/$$/fd
total 0
lrwx------. 1 root root 64 Oct 14 09:53 0 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 09:53 1 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 09:53 2 -> /dev/pts/0
lrwx------. 1 root root 64 Oct 14 09:53 255 -> /dev/pts/0
lr-x------. 1 root root 64 Oct 14 09:53 8 -> /etc/profile

​ 可以看到我们的bash多了一个输入文件描述符8指向文件/etc/profile

# read输入内容
[root@localhost ~]# read var04 0<& 8

# 查看内容
[root@localhost ~]# echo $var04
# /etc/profile

# 用cat输入,查看内容
[root@localhost ~]# cat 0<& 8
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
……

​ 这里我们使用重定向操作符<&来复制输入文件描述符8给命令cat的标准输入0

​ 类似的输出使用>&重定向操作符

# 创建out.txt
[root@localhost ~]# touch out.txt

# 定义输入文件9
[root@localhost ~]# exec 9> out.txt

# 将输出结果输入到9(输入文件/root/out.txt)中
[root@localhost ~]# ls -l ./ >& 9

# 查看out文件
[root@localhost ~]# cat out.txt
total 16
-rw-r--r--. 1 root root 1132 Oct 14 09:38 lsall.txt
-rw-r--r--. 1 root root  100 Oct 14 09:35 lserr.txt
-rw-r--r--. 1 root root 2164 Oct 14 09:35 ls.txt
-rw-r--r--. 1 root root    0 Oct 14 10:00 out.txt
-rw-r--r--. 1 root root   86 Oct 14 09:49 test.sh

# 将错误信息输入到out中
[root@localhost ~]# ls -l /god 2>& 9

# 查看
[root@localhost ~]# cat out.txt
ls: cannot access /god: No such file or directory

​ 这里再次强调重定向操作符前如果给出文件描述符,不能出现空格

# 关闭文件描述符
[root@localhost ~]# exec 8<&-

[root@localhost ~]# exec 9<&-

​ 以上是关闭文件描述符

# 将输出信息,输入到out中
[root@localhost ~]# ls -l /god >& 9

# 输出错误,把9作为文件,在当前目录创建了9
[root@localhost ~]# ls -l /god &> 9 
[root@localhost ~]# ll
total 24
-rw-r--r--. 1 root root   49 Oct 14 10:06 9
-rw-r--r--. 1 root root 1132 Oct 14 09:38 lsall.txt
-rw-r--r--. 1 root root  100 Oct 14 09:35 lserr.txt
-rw-r--r--. 1 root root 2164 Oct 14 09:35 ls.txt
-rw-r--r--. 1 root root   49 Oct 14 10:05 out.txt
-rw-r--r--. 1 root root   86 Oct 14 09:49 test.sh

​ 以上两种都是特殊写法

​ >&操作符后面有两种情况:数值/字符串

​ 数值:一定是一个有效的文件描述符

​ 字符串:代表一个有效的文件

​ 而&>操作符只能接文件

# 允许允许的命令:
[root@localhost ~]# ls -l /god >& 9
ls: cannot access /god: No such file or directory

​ 如果换成:ls-l /god &> 9,则不能将标准输出和错误输出到9的文件中

​ 所以根据自己的情况,如果明确想文件输出推荐使用&>

四、重定向综合案例—一切皆文件

/dev/tcp/www.baidu.com/80将百度的地址端口映射为文件系统路径

​ 开启文件描述符实际是对baidu的socket连接

[root@localhost ~]# exec 12<> /dev/tcp/www.baidu.com/80

​ 通过echo的标准输出,将http协议的请求头输出到12文件描述符,起始就是通过socket发送给baidu的服务器

[root@localhost ~]# echo -e "GET / HTTP/1.0\n" >& 12

​ baidu服务器的返回可用通过12文件描述符读取到

[root@localhost ~]# cat <& 12
HTTP/1.0 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 9508
Content-Type: text/html
……

​ 注意,这个执行过程要快,时间长了,socket就超时断开连接了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2218267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于System.js的微前端实现(插件化)

目录​​​​​​​ 写在前面 一、微前端相关知识 &#xff08;一&#xff09;概念 &#xff08;二&#xff09; 优势 &#xff08;三&#xff09; 缺点 &#xff08;四&#xff09;应用场景 &#xff08;五&#xff09;现有框架 1. qiankun 2. single-spa 3. SystemJ…

【MR开发】在Pico设备上接入MRTK3(一)——在Unity工程中导入MRTK3依赖

写在前面的话 在Pico上接入MRTK3&#xff0c;目前已有大佬开源。 https://github.com/Phantomxm2021/PicoMRTK3 也有值得推荐的文章。 MRTK3在PICO4上的使用小结 但由于在MacOS上使用MRTK3&#xff0c;无法通过Mixed Reality Feature Tool工具管理MRTK3安装包。 故记录一下…

Dockerr安装Oracle以及使用DBeaver连接

拉取镜像 pull container-registry.oracle.com/database/free:latest 创建容器 说明一下我现在的最新版本是23 docker run -d --name oracle23i -h xrilang -p 1521:1521 container-registry.oracle.com/database/free:latest 查看日志 docker logs oracle23i 设置密码 因为创建…

登录时用户名密码加密传输(包含前后端代码)

页面输入用户名密码登录过程中&#xff0c;如果没有对用户名密码进行加密处理&#xff0c;可能会导致传输过程中数据被窃取&#xff0c;就算使用https协议&#xff0c;在浏览器控制台的Request Payload中也是能直接看到传输的明文&#xff0c;安全感是否还是不足。 大致流程&a…

第二百八十八节 JPA教程 - JPA查询连接OrderBy示例

JPA教程 - JPA查询连接OrderBy示例 以下代码显示如何使用ORDER BY子句和连接条件。 List l em.createQuery("SELECT e " "FROM Project p JOIN p.employees e " "WHERE p.name :project " "ORDER BY e.name").setParameter("pr…

【MogDB】MogDB5.2.0重磅发布第四篇-支持windows版gsql,兼容sqlplus/sqlldr语法

一、背景 目前仍然很多客户的运维机使用windows操作系统&#xff0c;开发人员也是在windows环境上进行编码测试&#xff0c;甚至还有一些客户管理比较严格&#xff0c;禁止开发人员登录服务器进行操作。在MogDB 5.2.0版本之前&#xff0c;没有提供windows平台的gsql&#xff0…

在龙芯笔记本电脑上安装loongnix20

在龙芯笔记本电脑上安装loongnix20。该笔记本电脑原来安装了统信操作系统20。使用时发现屏幕调到最暗还是偏亮。使用起来不方便。于是安装另外一款操作系统loongnix20。 于是下载loongnix20。下载速度很快。下载以后安装也比较顺利。装好试了一下&#xff0c;屏幕亮度可以调到…

二叉树中的最长交错路径

题目链接 二叉树中的最长交错路径 题目描述 注意点 每棵树最多有 50000 个节点每个节点的值在 [1, 100] 之间起点无需是根节点 解答思路 要找到最长交错路径&#xff0c;首先想到的是深度优先遍历因为起点无需是根节点&#xff0c;所以对于任意一个节点&#xff0c;其可以…

分类任务中评估模型性能的核心指标

在机器学习尤其是分类任务中&#xff0c;Accuracy&#xff08;准确率&#xff09;、Precision&#xff08;精确率&#xff09;、Recall&#xff08;召回率&#xff09;和F1 Score&#xff08;F1分数&#xff09;是评估模型性能的四个核心指标。每个指标都有其独特的含义和用途&…

JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?

大厂面试真题:GC 算法有多少种&#xff1f;各自优缺点是什么&#xff1f;年轻代和年老代选择哪种算法最优&#xff1f; 首先回顾一个图&#xff0c;也就是.class文件的类加载过程&#xff0c;以及线程执行、java内存模型图。看过系列1、2、3三篇文章的同学&#xff0c;大脑先回…

[产品管理-46]:产品组合管理中的项目平衡与管道平衡的区别

目录 一、项目平衡 1.1 概述 1.2 项目的类型 1、根据创新程度和开发方式分类 2、根据产品开发和市场周期分类 3、根据风险程度分类 4、根据市场特征分类 5、根据产品生命周期分类 1.3 产品类型的其他分类 1、按物理形态分类 2、按功能或用途分类 3、按技术或创新程…

大数据研究实训室建设方案

一、概述 本方案旨在提出一套全面的大数据研究实训室建设策略&#xff0c;旨在为学生打造一个集理论学习与实践操作于一体的高端教育环境。实训室将专注于培养学生在大数据处理、分析及应用领域的专业技能&#xff0c;通过先进的设施配置、科学的课程体系和实用的实训模式&…

C++之list(2)

list(2) list的迭代器 const迭代器 根据我们之前学过的知识&#xff1a; const int*p1;//修饰的是指向的内容 int *const p2;//修饰的是迭代器本身我们写const迭代器&#xff0c;期望的是指向的内容不能修改。 所以更期望写上面p1的形式 const迭代器与普通迭代器的不同点在于…

03 设计模式-创造型模式-单例模式

单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建…

C语言复习第4章 数组

目录 一、一维数组的创建和初始化1.1数组的创建1.2 变长数组1.3 数组的初始化1.4 全局数组默认初始化为01.5 区分两种字符数组1.6 用sizeof计算数组元素个数1.7 如何访问数组元素1.8 一维数组在内存中的存储(连续存储)1.9 访问数组元素的另一种方式:指针变量1.10 数组越界是运行…

【AI绘画】Midjourney进阶:引导线构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;引导线构图特点使用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midjourney进阶&a…

AnaTraf | TCP重传的工作原理与优化方法

目录 什么是TCP重传&#xff1f; TCP重传的常见触发原因 TCP重传对网络性能的影响 1. 高延迟与重传 2. 吞吐量的下降 如何优化和减少TCP重传 1. 优化网络设备配置 2. 优化网络链路 3. 网络带宽的合理规划 4. 部署CDN和缓存策略 结语 AnaTraf 网络性能监控系统NPM | …

网络最快的速度光速,因此‘‘光网络‘‘由此产生

世界上有一种最快的速度又是光,以前传统以太网络规划满足不了现在的需求。 一 有线网规划 二 无线网规划

如何用pyhton修改1000+图片的名字?

import os oldpath input("请输入文件路径&#xff08;在windows中复制那个图片文件夹的路径就可以):") #注意window系统中的路径用这个‘\分割&#xff0c;但是编程语言中一般都是正斜杠也就是’/‘ #这里写一个代码&#xff0c;将 \ > / path "" fo…

嵌入式职业规划

嵌入式职业规划 在嵌入式的软件开发中&#xff0c;可以分为&#xff1a; 嵌入式MCU软件开发工程师&#xff1b; 嵌入式Linux底层&#xff08;BSP&#xff09;软件开发工程师&#xff1b; 嵌入式Linux应用开发工程师&#xff1b; 嵌入式FPGA算法开发工程师 对于前两个阶段 …