linux shell

2023-05-16

转自:http://blog.csdn.net/fly_sky520/article/details/8853537

最近在linux下面编写shell脚本,差不多是边学边写。在此记录一些学习心得。

一)shell的引号。

shell的引号有单引号',双引号",反引号`。

由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。

由双引号括起来的字符,除$、倒引号(`)和反斜线(\)仍保留其特殊功能外,其余字符均作为普通字符对待。“$”表示变量替换,即用其后指定的变量的值来代替$和变量;倒引号表示命令替换;仅当“\”后面的字符是下述字符之一时,“\”才是转义字符,这些字符是:“$”、“`”、“"”、“\”或换行符。转义字符告诉Shell不要对其后面的那个字符进行特殊处理,只是当作普通字符。

倒引号括起来的字符串被shell解释为命令行,在执行时,Shell会先执行该命令行,并以它的标准输出结果取代整个倒引号部分。

二)目录权限。

文件或目录的访问权限分为只读(r),只写(w)和可执行(x)三种。

当我们用ls -l命令的时候,会看到如下内容


其中第一列我们看到了-rw-r--r--的字符,这个就表示当前的文件的权限。

横线代表空许可。注意这里共有10个位置。第一个字符指定了文件类型。在通常意义上,一个目录也是个文件。如果第一个字符是横线,表示是个非目录的文件。如果是d,表示是个目录。除第一个位置外,剩下的每连续三个表示一个权限,第一个连续三字符表示文件拥有者的权限,比如这里的”rw-“表示文件拥有着具有可读可写的权限。第二个连续三字符”r--“表示文件拥有着所在组具有的权限,这里的”r--“表示只读。后面连续三字符表示所有用户的权限,也是只读。

在权限设置中,我们为了简化这种权限设置,通常把r、w、x分别用4、2、1表示,然后把它们相加表示文件的权限。比如上面的两个文件的权限就是644。又比如一个文件的权限是754,那就表示文件的拥有者具有可读可写可执行的权限,所在组具有读和执行的权限,其他用户具有读的权限。

我们可以通过chmod来修改一个文件的权限。这里有两种方式,首先是数字设定法,我们只需要运行下面的命令


或者使用文字设定法,如下


文字设定法中的u+x,g-w-r,o-x-r就表示设定权限,其中u,g,o分别表示文件拥有者,所在组用户,其他用户,而+,-对应增加与删除权限。

当然使用chmod修改文件权限只能是超级用户和文件的拥有者。

除此之外,我们还能用户chgrp修改文件所属组,chown修改文件所属用户或组。

语法:chgrp [选项] 用户组 文件

语法:chown [选项] 用户或组 文件


三)变量。

shell中的变量不需要声明,赋值的话直接[变量名=值]就可以了。比如

[plain]  view plain copy
  1. num=1  
  2. me=fly  

在shell中变量引用有几个需要注意的地方,比如你在脚本中使用下面的语句时

[plain]  view plain copy
  1. echo "I'm ${me}Baby"  
这时候就不能直接使用$meBaby,因为shell解释的时候就会去找meBaby这个变量。而你只有me这个变量。

在shell中实现变量的运算时,需要注意几个地方,看下图的执行结果


从上面的执行结果我们可以看出,使用shell变量就行运算的时候,可以使用中括号,双小括号,以及expr运算关键字。

除了以上基本的变量外,shell里面还有一些特殊的参数。如下面的参数:

[plain]  view plain copy
  1.  $0 = shell名称或shell脚本名称 $1 = 第一个shell参数 ...   
  2.  $9 = 第九个shell参数 $# = 位置参数的个数   
  3.  "$*" = "$1 $2 $3 $4 .. $n",以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个。  
  4.  "$@" = "$1" "$2" "$3" "$4" .. "$n",与$#相同,但是使用时加引号,并在引号中返回每个参数。  
  5.  $# 传递到脚本的参数个数。  
  6.  $- 显示shell使用的当前选项,与set命令功能相同。  
  7.  $? = 最近执行的命令的退出状态,0表示没有错误,其他任何值表明有错误。  
  8.  $$ = 当前shell脚本的PID。  
  9.  $! = 最近启动的后台作业的PID。   
  10.   形式           如果设置了var   如果没设置var   
  11.  ${var:-string}     $var            string   
  12.  ${var:+string}     string          null   
  13.  ${var:=string}     $var            string (并执行var = string)   
  14.  ${var:?string}     $var            返回string然后退出   
  15.   形式               结果   
  16.  ${var%suffix}     删除位于var结尾的最小匹配模式   
  17.  ${var%%suffix}    删除位于var结尾的最大匹配模式   
  18.  ${var#suffix}     删除位于var开头的最小匹配模式   
  19.  ${var##suffix}    删除位于var开头的最大匹配模式  

四)条件与循环。

跟其他编程语言一样,shell中包含if条件语句,while,for,until循环,以及case和select语句。首先介绍if条件语句

if语句结构[if/then/elif/else/fi],其中[ ]与变量之间有空格。

[plain]  view plain copy
  1. if [ $y -eq 1 ];then  
  2. <span style="white-space:pre">  </span>y=$(($y+1))  
  3. else  
  4. <span style="white-space:pre">  </span>y=1  
  5. fi  
shell命令,可以按照分号分割,也可以按照换行符分割。如果想一行写入多个命令,可以通过“';”分割。

[plain]  view plain copy
  1. num=3;if [ $num -eq 1 ] ;then echo 1; elif [ $num -eq 2 ] ;then echo 2;else echo 3;fi;  
在if条件语句中,可以对数字字符串进行大小,匹配比较,还可以对文件夹、文件的权限、存在与否进行判断。

五)函数。

六)时间。

七)grep,sed,awk,tr等工具的使用。

我们从例子入手,下面有一个文件f中的域名取出并排序,内容如下,

[plain]  view plain copy
  1. http://www.fly_sky520.org/index.html  
  2.   
  3. http://www.fly_sky520.org/1.html  
  4.   
  5. http://post.fly_sky520.org/index.html  
  6.   
  7. http://mp3.fly_sky520.org/index.html  
  8.   
  9. http://www.fly_sky520.org/3.html  
  10.   
  11. http://post.fly_sky520.org/2.html  
*注意,各行之间有空行。下面看我的操作

1)首先利用grep与awk工具。

该方法先利用grep -v 取非空行数据,-v参数是反向检索的意思。效果如下:


然后利用awk工具取以"/"分隔符分割的第三个参数,也就是域名了。


最后利用sort进行排序,用nuiq -c计数


所以第一个完整命令就是

[plain]  view plain copy
  1. cat f | grep -v '^$'|awk -F/ '{print $3}'|sort|uniq -c  

2)利用tr与grep工具

首先利用tr工具的替换功能


再利用grep工具查找包含域名的项


最后排序计数


所以完整命令就是

[plain]  view plain copy
  1. cat f |tr "\/" "\n" | grep fly | sort | uniq -c  


3)利用cut与tr工具

首先使用cut工具取出域名

cut -d/ -f3的意思就是把文件内容以“/”作为分隔符,并去取出第三部分显示。-d就是自定义分隔符的意思,默认分隔符为制表符,-f就是显示区域

然后,我们再利用tr工具去除空行


最后排序计数


所以最后的方法为

[plain]  view plain copy
  1. cut -d/ -f3 f|tr -s '\n'|sort | uniq -c  

4)利用sed工具

首先利用sed工具去除空行


sed命令中d为删除的意思。//之间为正则表达式^$表示空行。然后再利用sed的‘s///g’字符替换功能


最后还是排序计数



sed的编辑功能相当强大,比如我要修改配置文件f中【name  = “Fly” 】的name为Sky。我只需要输入以下命令


其中-i就是直接修改文件内容的选项,这个命令的操作就是通过/name/先查找出name行,然后修改对应的值。

下面是一些sed的例子

[plain]  view plain copy
  1. 6. 实例    
  2. 删除:d命令    
  3. $ sed '2,$d' example-----删除example文件的第二行到末尾所有行。    
  4. $ sed '$d' example-----删除example文件的最后一行。   
  5. 替换:s命令  
  6. $ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。    
  7. $ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。  
  8. $ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。   
  9. $ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。    
  10. 选定行的范围:逗号  
  11. $ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。   
  12. $ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。  
  13. $ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。    
  14. 多点编辑:e命令    
  15. $ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执 行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。    
  16. $ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。    
  17. 从文件读入:r命令   
  18. $ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。    
  19. 写入文件:w命令   
  20. $ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。    
  21. 追加命令:a命令   
  22. $ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。    
  23. 插入:i命令    
  24. $ sed '/test/i\\    
  25. new line    
  26. -------------------------' example    
  27. 如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。    
  28. 下一个:n命令    
  29. $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。    
  30. 变形:y命令    
  31. $ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。    
  32. 退出:q命令    
  33. $ sed '10q' example-----打印完第10行后,退出sed。    
  34. 保持和获取:h命令和G命令  
  35. $ sed -e '/test/h' -e '$G example-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保 持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中 的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。    
  36. 保持和互换:h命令和x命令    
  37. $ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。    
以上实例内容摘自网友icyheart的帖子,地址是http://www.iteye.com/topic/587673。

八)定时任务。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux shell 的相关文章

  • 将 jar 作为 Linux 服务运行 - init.d 脚本在启动应用程序时卡住

    我目前正在致力于在 Linux VM 上实现一个可运行的 jar 作为后台服务 我已经使用了找到的例子here https gist github com shirish4you 5089019作为工作的基础 并将 start 方法修改为
  • docker容器大小远大于实际大小

    我正在尝试从中构建图像debian latest 构建后 报告的图像虚拟大小来自docker images命令为 1 917 GB 我登录查看尺寸 du sh 大小为 573 MB 我很确定这么大的尺寸通常是不可能的 这里发生了什么 如何获
  • jq中如何分组?

    这是 json 文档 name bucket1 clusterName cluster1 name bucket2 clusterName cluster1 name bucket3 clusterName cluster2 name bu
  • 如何更改 Apache 服务器的根目录? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何更改 Apache 服务器的文档根目录 我基本上想要localhost从 来 users spencer projects目录而不是
  • MySQL 中的创建/写入权限

    我的设备遇到一些权限问题SELECT INTO OUTFILE陈述 当我登录数据库并执行简单的导出命令时 例如 mysql gt select from XYZ into outfile home mropa Photos Desktop
  • 快速像素绘图库

    我的应用程序以每像素的方式生成 动画 因此我需要有效地绘制它们 我尝试过不同的策略 库 但结果并不令人满意 尤其是在更高分辨率的情况下 这是我尝试过的 SDL 好的 但是慢 OpenGL 像素操作效率低下 xlib 更好 但仍然太慢 svg
  • 在退出脚本之前等待后台进程完成

    在退出脚本 TCL Bash 之前 如何确保所有后台进程已完成执行 我正在考虑将所有后台进程 pid 写入 pid 文件 然后最后 pgrep pidfile 以查看在退出之前是否有任何进程仍在运行 有一些更简单的方法可以做到这一点吗 TC
  • 高效的内存屏障

    我有一个多线程应用程序 其中每个线程都有一个整数类型的变量 这些变量在程序执行期间递增 在代码中的某些点 线程将其计数变量与其他线程的计数变量进行比较 现在 我们知道在多核上运行的线程可能会无序执行 一个线程可能无法读取其他线程的预期计数器
  • 在 Mac OSX 上交叉编译 x86_64-unknown-linux-gnu 失败

    我尝试将我的 Rust 项目之一编译到 x86 64 unknown linux gnu 目标 cargo build target x86 64 unknown linux gnu Compiling deployer v0 1 0 fi
  • Capistrano 3 部署无法连接到 GitHub - 权限被拒绝(公钥)

    我使用 Capistrano v3 和 capistrano symfony gem 设置了以下部署脚本 我正在使用 Ubuntu 14 4 部署到 AWS EC2 实例 我正在连接从 AWS 下载的 pem 文件 我的deploy rb中
  • git 错误:无法处理 https

    当我尝试使用 git clone 时https xxx https xxx我收到以下错误我不处理协议 https 有人可以帮我吗 完整消息 dementrock dementrock A8Se git 克隆https git innosta
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y
  • 在 shell 脚本中将一个子字符串替换为另一个字符串

    我有 我爱苏子并结婚 我想将 苏子 更改为 萨拉 firstString I love Suzi and Marry secondString Sara 期望的结果 firstString I love Sara and Marry 要更换
  • 限制 Imagemagick 使用的空间和内存

    我在 Rails 应用程序上使用 Imagemagick 使用 rmagick 但我的服务器 Ubuntu 不是很大 当我启动转换进程时 Imagemagick 占据了我的服务器 30GB HDD 的所有位置 内存 我想限制内存和 tmp
  • 每个命令都返回“bash:<命令>:找不到命令...”[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我刚刚安装了 Scala 并添加了路径gedit bashrc export SCALA HOME home avijit sca
  • 如何在 GNU/Linux 上设置 Subversion (SVN) 服务器 - Ubuntu [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一台运行 Ubuntu 的笔记本电脑 我想将其用作 Subversion 服务器 既让我自己在本地承诺 也让其他人远程承诺 要使其
  • Gearman,php 扩展问题:使用终端在 .. 中找不到类“GearmanWorker”,但可以在浏览器上使用

    我最近在 ubuntu 10 04 上安装了 gearman 并安装了它的 pecl 扩展 现在 当我在浏览器中运行一个 php 文件时 其中包含 client new GearmanWorker die var Dump client I
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • Fedora dnf 更新不起作用?

    当我尝试使用 update 命令更新 Fedora 22 时 sudo dnf update 我收到以下错误 错误 无法同步存储库 更新 的缓存 无法准备内部镜像列表 Curl 错误 6 无法解析主机名 无法解析主机 mirrors fed

随机推荐