shell中的(叙述什么是shell)

一.目录。sed的经典例子如何显示/etc/passwd的倒数第二行?二。awk的经典例子用awk输出hello world,在hello后面加上单引号。三。外壳解析的基本步骤。大括号扩展波浪线来扩展变量,而不是扩展算术扩展文件。通配符扩展1。如何解决*无法匹配以开头的文件?2.如何解决递归到子目录进行匹配的问题?去掉引号搜索命令fork exec执行命令eval命令经常用来写shell,那么shell是怎么解析的呢?
一.系统经济对话的经典例子。$符号被解析为shell中的一个变量,但是它表示sed中文件的最后一行。
如何显示/etc/passwd的倒数第二行
redirect]# sed-n ‘ $-2p ‘/etc/passwd
这个显然不行。sed内部有一个行号计数器,逐行读取直到最后一行,$是最后一行的行号。怎么解决?先用wc -l计数,然后传入变量,再打印倒数第二行。
redirect]# line=25 redirect]# sed-n ‘ $ { line } p ‘/etc/passwd
注意不能用单引号。单引号是强引用,所以不能解析变量。如何同时显示最后一行和倒数第二行?
redirect]# sed-n ‘ $ { line } p;$ p ‘/etc/passwdtcpdump : x :723:723:/:/sbin/nologin
为什么只显示倒数第三行?第二个$属于sed的最后一行,不应该暴露给shell解析。
redirect]# sed-n ‘ $ { line } p;’$ p ‘/etc/passwdtcpdump : x :7233:723:/:/sbin/nologinrpcuser : x :293: RPC服务用户:/var/lib/NFS :/sbin/nologin
这也是可能的。
redirect]# sed-n ‘ $ { line } p;\ $ p ‘/etc/passwdtcpdump : x :723:723:/:/sbin/nologinrpcuser : x :293: RPC服务用户:/var/lib/NFS :/sbin/nologin
redirect]# sed-n ‘ { line } ‘ p;\ $ p ‘/etc/passwdtcpdump : x :723:723:/sbin/nologinrpcuser : x :293: RPC服务user :/var/libre direct]# sed-n $ { line } ‘ p;\ $ p ‘/etc/passwdtcpdump : x :723:723:/:/sbin/nologinrpcuser : x :293: RPC服务用户:/var/lib/NFS :/sbin/nologin
二、awk的经典例子
使用awk输出hello world,在hello后面加上单引号。
redirect]# awk ‘ BEGIN { print ‘ hello world ‘ } ‘ hello world
redirect]# awk ‘ begin { print ‘ hello ‘ ‘ ‘ ‘ world ‘ } ‘ hello ‘ world ‘ look ‘ begin { print ‘ hello ‘ ‘ ‘ ‘ world ‘ } ‘
redirect]# awk ‘ begin { print ‘ hello ‘ world \ ‘ } ‘ hello ‘ world 047是单引号的ASSIC值redirect]# awk ‘ begin { print ‘ hello \ 07 world ‘ } ‘ hello ‘ world # print,双引号的值保留给awk-v q=’ ‘ ‘ begin { print ‘ hello ‘ q ‘ world ‘ } ‘ hello ‘ world。
三、shell解析的基本步骤
大括号扩展以生成数字
to_delete]# echo {1.10 } 1 2 3 4 5 6 7 8 9 10[root @ to _ delete]#[root @ to _ delete]# echo { a.e}a b c d e
批量创建文件:
to_delete]# touch /tmp/{a.d}。原木
线路扩展回显~导出器目录
Echo ~输出当前目录,相当于pwd
Echo ~-输出上一级目录
变量替换扩展不仅可以解释变量,还可以解释变量表达式。例如,截取字符s之前的内容。%%s*从左到右贪婪删除。
~]# echo $ name nine sun ~]# echo $ { name % % s * }九
第二个单词拆分:
~]# echo $(echo-e ‘ hello \ n world ‘)hello world ~]# echo ‘ $(echo-e ‘ hello \ n world ‘)’ hello world
算术扩展
to _ delete]# a=4[root @ to _ delete]# echo $((a 5))9
文件通配符扩展shopt命令用于显示和设置shell中的行为选项,可以增强shell的可用性。Shopt [-psu] [optname …]-s打开一个选项。-u关闭一个选项。-p列出所有可设置的选项。
1.如何解决*无法匹配以开头的文件的问题?shopt -s dotglob开放点的通配符扩展
dotglob如果设置,bash包含以`开头的文件名。在路径名扩展的结果中。
tmp]# ls/root/* sshls :无法访问“/root/* ssh”3360 no shufile或directory #无法匹配[root @ tmp]# shopt-s dot glob[root @ tmp]# ls/root/* ssh authorized _ keys
2.如何解决递归到子目录进行匹配的问题?直接搜索,在fork子目录下找不到文件。
Shopt -s globstar打开递归搜索文件的通配符扩展
globstar如果设置,路径名扩展上下文中使用的模式**将匹配所有文件以及零个或多个目录和子目录。如果模式后面跟有/,则只有目录和子目录匹配。
Grep -l ‘printf’ **/*。c**代表递归当前目录-l只列出文件名,不列出内容。这也是grep的一个有用参数。
tmp]# shopt-s globstar[root @ tmp]# grep-l ‘ printf ‘ * . cfork . c[root @ tmp]# grep-l ‘ printf ‘ * */* . cfork . ctest/fork _ 1 . c[root @ tmp]# grep-l ‘ printf ‘ */*。ctest/fork_1.c# **不仅递归到一级目录,还可以递归到多级子目录。tmp]# grep-l ‘ printf ‘ * */* . cfork . cfork/fork _ 2/fork _ 2.ctest/fork _ 1 . c
未引用类别’/proc/self/cmdline ‘
搜索命令
Fork execfork是一个子bash进程,其中加载exec来替换子bash并执行。
执行子bash的进程退出代码被返回给父进程。
shell解析命令行的过程
看完这个过程,你会发现shell编程中单引号和双引号的真正含义。比如echo ‘~ ‘和echo ~的输出为什么不一样?回显的输出结果“{1.10}和echo {1.10}是不同的。
name=longshuaia=24echo -e ‘某些文件: ‘ ~/I * ‘ \ n日期:$(日期%F)\n$name的年龄是$((a 4))’ /tmp/a.log
解释一下上面的shell脚本。
eval命令\ $的使用被视为一个普通的$符号而不是变量的标识。$a替换为helloeval echo $hello。此时,eval不执行自身,而是变成echo $hello。
[root @ Hadoop 100 ~]# a=hello您在/var/spool/mail/root[root @ Hadoop 100 ~]#[root @ Hadoop 100 ~]# hello=ninesun[root @ Hadoop 100 ~]#[root @ Hadoop 100 ~]# echo $ a hello[root @ Hadoop 100 ~]# echo \ $ a $ a[root @ Hadoop 100 ~]#[root @ Hadoop 100 ~]# eval echo \ $ a hello
命令行处理步骤-更新2022年2月11日09336040:54要成为一个真正的shell脚本编程专家(或者调试一些棘手的问题),你需要了解命令行处理涉及的步骤,尤其是这些步骤的顺序。从shell STDIN或脚本中读取的每一行都称为管道,因为它包含一个或多个由零个或多个管道字符(|)分隔的命令。
对于读取管道,shell会将其分解为命令,设置管道的I/O,然后对每个命令执行以下操作。将命令分成一组固定的元字符(空格、制表符、换行符等);(,),|,)分隔的词法单元(token)。词法单元的类型包括单词、关键字、I/O重定向和分号。检查每个命令的第一个词法单元是否是不带引号或反斜杠的关键字。如果属于起始关键字,比如If或者其他控制结构的开头,function,{,(),那么这个命令就是复合命令。shell将在内部为它做相关的准备,读取下一个命令,并重新开始这个过程。如果关键字不是复合命令的开头(例如,then,else,do,这是控制结构的“中间”部分;Fi、done,它们属于控制结构的“端”;或者逻辑运算符),shell会提示一个语法错误。对照别名列表检查每个命令的第一个单词。如果匹配,用别名定义替换单词,然后返回步骤1;否则,继续步骤4。此方法允许出现递归别名,还允许为关键字定义别名(例如,alias aslongas=while或alias procedure=function)。执行花括号扩展。比如把a{b,c}推广到ab ac。如果波浪线在单词的开头,则替换为用户的主目录($HOME)。例如,用用户的主目录替换~user。对以美元符号($)开头的表达式执行参数(变量)替换。对形式为$(字符串)的表达式执行命令替换。计算$((字符串))形式的算术表达式。将命令行中的参数替换、命令替换和算术求值的结果再次分成一系列的单词。这一次,$IFS中包含的字符被用作分隔符,而不是步骤1中的元字符。对出现的*,[]执行路径扩展,即通配符扩展。将第一个单词作为命令,按照以下顺序找到它的来源:首先是函数名,然后是内置命令,最后是$PATH中包含的目录中的文件。在设置了I/O重定向和其他事项之后,执行此命令。有相当多的步骤,甚至这还不是全部!在继续之前,我们应该用一个例子来阐明这个过程。假设您要执行以下命令:alias ll=’ls -l ‘。进一步,假设用户alice (/home/alice)的主目录有一个名为hist537的文件,还有一个双美元符号变量$ $的值为2357(记住,$ $保存了进程ID,它在所有正在运行的进程中是唯一的)。现在让我们看看shell如何处理下面的命令。
Ll $ (type-pathcc) ~ Alice/。* $(($ $ 00)ll $(type-path cc)~ Alice/。* $ (($ $00))把它分成一系列单词。Ll不是关键字,而是小写的L,所以在步骤2中什么都不做1。Ls -l $ (type-pathcc) ~ Alice/。* $ ($ $00))用ls-l替换别名ll .然后shell重复步骤1 ~ 3;步骤2将把ls -l拆分成2个单词。Ls-l $ (type-pathcc) ~ Alice/。* $ (($ $00))不执行任何操作。Ls-l $ (type-pathcc) /home/alice/。* $ ($ $00))展开~alice成/home/Alice。Ls-l $ (type-pathcc)/home/Alice/。* $ ((2537 00))将$ $替换为2537。Ls-l/usr/bin/cc/home/Alice/。* $ ((2537 00))对类型路径cc执行命令替换。Ls-l/usr/bin/cc/home/Alice/。* 537计算算术表达式2537 00。Ls-l/usr/bin/cc/home/Alice/。* 537什么都不做。ls-l/usr/bin/cc/home/Alice/. hist 537替换通配符表达式。文件名为*537。在/usr/bin中找到命令ls。使用选项-l和两个参数执行/usr/bin/ls。1此处提到的X步骤对应于前面文本中相应的编号步骤。虽然这些步骤相当直观,但它们只是部分的。还有五种方法可以改变这个过程:引用;使用命令,内置,启用;使用高级命令eval。
单引号(“”)可以完全绕过步骤1~10,包括别名。单引号中的所有字符保持不变。单引号不能再次出现,即使它前面有反斜杠(\)。双引号(‘)可以绕过步骤1~4和9~10。也就是说,它忽略管道字符、别名、代字号替换、通配符扩展,以及用分隔符(如空格字符)将双引号的内容分成一系列单词。但是,双引号仍然执行参数替换、命令替换和算术表达式求值。双引号可以出现在双引号里,只要在它们前面加一个反斜杠(\)就可以了。另外,必须使用反斜杠对$,'(古代命令替换分隔符),\进行特殊含义的转义。表C-1给出了一个简单的例子,演示了引用是如何工作的。假设执行的语句是person=hatter,用户alice的主目录是/home/alice。

其他教程

Java太老不能吃?2020 Java生态系统报告发布

2022-8-28 3:25:34

其他教程

在周予同的家里,我最想偷的是一面镜子?

2022-8-28 3:27:47

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索