一起学Shell之(六)输入、输出、文件与命令执行

简介:

 

#----------------------------------------------------------#

# ====> 红色字体 -特指煮酒个人所见。加粗则为需要重点注意。 #

# ====>  蓝色加粗 -特指与本文相关人员,包括参与修正的朋友。 #
# ====> 煮酒品茶 -Http://cwtea.blog.51cto.com          #
#----------------------------------------------------------#

 

序:完整介绍shell语言,如何以不同的方式处理输入、输出和产生文件名,接着是命令替换,命令行参数。各类引用。重点命令行,讨论shell提供的各类引用,最后则是命令执行顺序,并针对内建于shell里的命令作介绍。

 
标准输入、标准输出与标准错误输出:
 
执行过程:读取标准输入、写入标准输出,并将错误信息传递给标准错误输出。我们称它为过滤器,因为它们过滤数据流,每一个都会在数据流上执行某种运算,再通过管道,将它传递给下一个。read读取行。
 
语法:read [ -r ] variable ...
 
用途:将信息读入一个或多个shell变量。
主要选项:
-r:原始读取,不作任何处理,不将行结尾处的反斜杠解释为续行字符。
行为模式:自标准输入读取行后,通过shell字段切割的功能(使用$IFS)进行切分,第一个单词赋值给第一个变量。第二个单词则赋值第二个变量,以此类推,如果单词多于变量,则所有剩下的单词,全赋值纪念品最后一个变量。read一量遇到文件结尾(end-of-file),会以失败值退出。如果输入行以反斜杠结尾,则read会丢弃反斜杠与换行字符,然后继续读取下一行数据,如果你有使用-r选项那么read便会以字面意义读取最后的反斜杠。
 
read可以一次读取所有的值到多个变量里,这种情况下,在$IFS里的字符会分隔输入行里的数据,使其成为各自独立的单词。
例:
------------------------
[root@localhost test]# cat read
printf "Enter name, rank, serial number: "
read name rank serno
echo $name
echo $rank
echo $serno
[root@localhost test]# ./read
Enter name, rank, serial number: cwtea 100 1101 #以空格方式
cwtea
100
1101
------------------------
 
重定向:
<,>,>>,| 
 
额外的重定向运算符
set -c
解释:Posix Shell提供了防止文件意义截断的选项:执行set -c命令可打开shell所谓的禁止覆盖选项(noclobber),当它在打开状态下时,单纯的>重定向遇到目标文件已存在时,就会失败。>|运算符则可令noclobber选项失效。提供行内输入的<<与<<-
 
格式:program << delimiter 可以在Shell脚本正文内提供输入数据。
默认情况下,shell可以在嵌入文件正文内做变量、命令和算术替换。
 
如果定界符以任何一种形式的引号括起来,shell便不会处理输入的内文:
------------------------------------------------
[root@bogon test]# cat de
i=5
cat << 'E'OF
this is i: $i
Here is $(a,b)
EOF
 
i=5
echo $i
[root@bogon test]# sh de
this is i: $i
Here is $(a,b)
5
----------------------------------------
第二种形式是有一个负号结尾,所有开头的制表符在传递纪念品程序作为输入之前,
 
都从嵌入文件与结束定界符中删除。
 
以<>打开一个文件作为输入与输出之用
program <> file 可供读取与写入操作。默认是标准输入上打开file.
< 是以只读打开 >是以只写打开。
 
exec
语法:exc [ program [ arguments ... ] ]
用途:以新的程序取代shell,或改变shell本身的I/O设置。
行为:搭配参数也就是使用指定的程序取代shell,以传递参数给它,如果只使用I/O重写向,则会改变shell本身的文件描述符。
 
Printf
语法:printf format [ string ... ]
用途:为了从Shell脚本中产生输出,由于printf的行为是由posix标准所定义,因此使用printf的脚本比使用echo更具可移植性。
 
行为:printf使用format字符串控制输出,字符串里的纯字符都如实打印,echo转义序列会被解释。包括%与一个字母的格式指示符,用来示相对应的参数字符串的格式化。
[图1]
 

 
-----------------------------
[root@bogon oldboy]# printf "a string, with processing: <%b>\n" "A\nB"
a string, with processing: <A
B>
[root@bogon oldboy]# 
-------------------------------
[图2]
 

 
根据Posix标准,浮点格式%e、$E、%f、%g和%G是“不需要被支持”。这是因为awk支持浮点算数运算,且有它自己的printf语句。这样,shell程序中需要将浮点数值进 行格式化的打印时,可使用小型 awk程序实现,然而,内建于bash、ksh93和zsh中的
 
printf命令都支持浮点格式。
 
printf命令可用来指定输出字段的宽度以及进行对齐方式。为实现此目的,接在%后面的格式表达式可采用三个可选用的修饰符以及前置的格式指示符。
%flags width.precision format-specifier输出字段的width为数字值,指定字段宽度时,字段的内容默认向右对齐,向左对齐,需要指定-标志。
-------------------------------------
[root@bogon cwtea]# printf "|%-20s|\n" hello
|hello               |
[root@bogon cwtea]# printf "|%20s|\n" hello
|               hello|
-------------------------------------
[图3]
 

 
----------------------------
[root@bogon cwtea]# printf "%.10o\n" 123
0000000173
[root@bogon cwtea]# printf "%.10s\n" "abcjaldd ddfds kfakdfal"
abcjaldd d
[root@bogon cwtea]# printf "%.2f\n" 1234.5528
1234.55
-----------------------------
[图4]
 

----------------------------
 
 
 
%d,i,o,u都是属数字类,对照表我们可以一一理解。
-----------------------------
[root@bogon cwtea]# width=5 prec=5 myvar=43.123456
[root@bogon cwtea]# printf "|%${width}.${prec}G|\n" $myvar
|43.123|
[root@bogon cwtea]# printf "|%5.5G|\n" 42.123456
|42.123|
-----------------------------
 
-----------------------------
[root@bogon cwtea]# printf "%s %#s\n" 15 15
15 15
[root@bogon cwtea]# printf "%05d\n" 15
00015
[root@bogon cwtea]# printf "|%10s|\n|%10s|\n" hello world
|     hello|
|     world|
-----------------------------
 
波浪号展开与通配符
shell有两种与文件名相关的展开,第一个是波浪号展开,另一个则有很多种叫法有人称之为通配符展开式,有人则称之为全局展开或是路径展开。波浪号展开:如果命令行字符串的第一个字符为波浪号(~),或是变量指定的值里任何未被引号括起来的冒号之后的第一个字符为波浪号(~)时,shell便会执行波浪号展开。
 
#cat ~/.profile shell将~换成$HOME,也就是当前用户的根目录。
#cat ~cwtea/.profile shell在系统的密码数据库中,寻找用户cwtea,再将~cwtea
换成cwtea的根目录
 
注意:有些商用unix不支持波浪号。
 
基本通配符:
任何的单一字符
* 任何的字符字符串
[set] 任何在set里的字符
[!set] 任何不在set里的字符
---------------------------
使用set结构的通配符
[abc] a、b、c
[.,;] 句号逗号或分号
[-_] 破折号或下划线
[a-c] a至c 包括a,b,c
[a-z] 任何小写字母
[!0-9] 任何非数字
[0-9!] 任何一个数字或惊叹号
[a-zA-Z]任何小写或大写字母
[a-zA-Z0-9_-]任何小写大写数据破折号和下划线
 
煮酒品茶:累加过程。了解下就成了。
 
注意:第一个为.的文件是隐藏文件。
 
命令替换:是指shell执行命令并将命令替换部分替换为执行该命令后的结果。命令替换的形式有两种。第一种是使用反引号、第二种是重音符号(`...`)的方式,将要执行的命令框起来。
 
[root@bogon ~]# cat `ls ~/yes`
 
为了怕产生混乱,难读所以采用korn shell里的一个功能$(...)
[root@bogon ~]# cat $(ls ~/yes)
 
 
引用:
反斜杠转义:\
单引号('...')
---------------------------
[root@bogon ~]# echo *
314494.htm 314590.htm 51 51cto 51cto.tar.gz 51test a anaconda-ks.cfg cwtea 
 
Desktop down down~ install.log install.log.syslog oldboy test title.htm 
 
yes yes.htm
[root@bogon ~]# echo '*'
*
-----------------------------
注意:单引号内的单引号无特别意义,如需请用双引号混合使用。
 
图[shell执行过程]
 
a="ls |more"
$a
 
shell会把|与more看作ls的参数,而不是直接产生一页页的文件列表。这是由于shell执行变量时,管道字符出现在步骤5,也就是在它确实寻找管道字符之后,变量的展开一直要到步骤8才进行解析,结果,shell把|与more看作ls的参数,使得ls会试图在当前目录下寻找名为|与more的文件!
 
--------------------
[root@bogon x]# a="ls | more"
[root@bogon x]# $a
ls: |: 没有那个文件或目录
ls: more: 没有那个文件或目录
------------------------------
[root@bogon x]# eval $a
f1
f2
out
-----------------------------
当shell到达最后一步时,会执行带有ls|more的参数eval,这会让shell回到步骤1.
 
[图shell内建命令]
 

 

 

command
语法:command [ -p ] program [ arguments ... ]
用途:在查找要执行的命令时,为了要避开shell的包含函数,这允许从函数中访问
 
与内建命令同名的命令的内建版本。
主要选项:-p 查找命令时,使用$PATH的默认值,保证找到系统的工具。
 
总结:read命令会读取行并将数据分割为各个字段,供赋值给指明的shell变量,搭
 
配-r选项 ,可控制数据要如何被读取。
 
I/O重定向允许你改变程序的来源与目的地,或者将多个程序一起执行于subshell或代码块里。除了重定向到文件和从文件重定向之外,管道还可以用于将多个程序连接在一起,嵌入文件则提供了行内输入。
 
文件描述符的处理是基本操作,特别是文件描述符1与2,会重复地用在日常的脚本编
写中。
 
printf是一个深具灵活性,但有点复杂的命令,用途是产生输出,大部分时候,它可
以简单地方式使用,但其实它的力量有时候是很有必要性具有深刻价值的。
 
shell会执行许多的展开或替换在每个命令行的文字上,波浪号展开式与通配符、变量展开、算术展开及命令替换。$() 为比较新、较好写的形式。
 
引用是为了保护不同的源代码元件,免于被shell作特殊处理, \ '' ""混合使用。
 
eval命令的存在是为了取代一般命令行替换与执行顺序,让shell脚本可以动态地构
建命令。
 
内建命令的存在是因为它们要改变shell的内部状态且必须是内建的,有些则是为了
效率。




本文转自 煮酒品茶 51CTO博客,原文链接:http://blog.51cto.com/cwtea/866347,如需转载请自行联系原作者

目录
相关文章
|
2月前
|
Shell
Shell 文件包含
10月更文挑战第5天
36 4
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
26天前
|
人工智能 Shell iOS开发
AI Shell:在命令行里“对话” AI ,微软推出将 AI 助手引入命令行的 CLI 工具,打造对话式交互命令行
AI Shell 是一款强大的 CLI 工具,将人工智能直接集成到命令行中,帮助用户提高生产力。AI Shell 支持多种 AI 模型和助手,通过多代理框架提供丰富的功能和灵活的使用模式。
83 7
|
1月前
|
Java Shell Windows
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
40 1
|
2月前
|
Web App开发 网络协议 Linux
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
这篇文章是关于Linux命令的总结,涵盖了从基础操作到网络配置等多个方面的命令及其使用方法。
77 1
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
|
2月前
|
Shell 知识图谱
Shell printf 命令
10月更文挑战第3天
25 1
|
2月前
|
Unix Shell Linux
常见的shell命令
shell常用命令
55 11
|
3月前
|
Shell Linux
Linux shell编程学习笔记82:w命令——一览无余
Linux shell编程学习笔记82:w命令——一览无余
|
2月前
|
Shell PHP
Shell echo命令
10月更文挑战第3天
23 0
|
2月前
|
JSON Java Shell
Dockerfile中RUN、CMD、ENTRYPOINT、SHELL命令的区别
理解这些指令的差异和应用场景,有助于构建高效、灵活且易于管理的Docker镜像。在实际应用中,根据需要选择合适的指令,可以有效地控制镜像构建和容器运行的行为。
218 0