Linux学习笔记之<Shell编程初入门>
2015-10-09 15:14
891 查看
薄雾浓云愁永昼,瑞脑消金兽。
佳节又重阳,玉枕纱橱,半夜凉初透
东篱把酒黄昏后,有暗香盈袖。
莫道不消魂,帘卷西风,人比黄花瘦。
本文的参考文档主要出自《Linux程序设计》第四版第二章。
可以看做是更符合国人思路的精简版。
本文不会很长,建议全篇阅读。
什么是Shell
管道和重定向
重定向输出
重定向输入
管道
作为程序设计语言的shell
shell的语法
变量
环境变量
条件
控制结构
函数
命令
默认情况下,上面这个命令会覆盖lsout.txt
若想在文件上追加
更多的内容:其实一个程序的输出不止一个。比如还有标准错误输出。(也许你之前没有接触到过,但是这点也很重要)
kill如果给一个已经结束的进程发送HUP信号,那么将会报错。
2代表的是标准错误输出。
如果将两者都输出到同一个文件,那么可以这样写
我们也可以丢弃掉输出的信息:
注意不要这样
管道构建时,这些命令是同时进行的,uniq>mydata.txt会清空掉mydata.txt
例如:
接下来需要把脚本设置为可执行权限:
然后
加上
这就是shell的命名方法,创建变量时不需要,但在获取它的值的时候必须加,但在获取它的值的时候必须加。
上面三种变量都是多少?
都是字符串:
读取输入赋值
参数变量
一个应用实例是:
打印出所有的参数名称:
当
或者这种:
(是不是shell编程很累啊?相比之下python的方式就要友好得多,靠缩进来说明结构,不需要then fi do done这些语句。但是这么做肯定是由当年的一些限制在里边。python要到1989年才能发明出来~)
[ -f mysh.sh ]可以看做test命令的变种。除了进行文件测试外:
还可以有字符串、算术等。具体可以看这里。
for循环一般是字符串
但是这样很明显太弱了,for还可以用通配符来拓展:
需要特别注意的是在ls f*.sh上加上$()
while语句:
朴素的密码验证
你会注意到$word加了一个引号,这么做是为了防止如下情形:
当word为空时,则变成了[ !=”secret” ]
case语句:
一个小栗子:
1.注意pattern其实是支持通配符的,*代表了一个字符串
2.注意一个case下可以有多条语句
没有返回类型,没有参数类型。
我们只谈两三个简单的例子:
捕获返回结果
一个复杂的点的返回0或1的函数
exec命令
exit n命令
expr命令
之前说过,无论是单引号双引号还是都是字符串。
类似于
正确的用法是:
你是否注意到这个
需要注意的是expr是一个命令,后面这个表达式每一个之间都有一个空格,这样命令才能正确识别。
如果我们要实现x的自加
printf命令
基本形式是:
示例
“Hi There”之所以也有双引号是因为需要将其看做一个整体。这一技巧还会在很多地方看到。
trap
在Shell编程中比较常用的两个外部命令:
find
find的具体指令请看这里。
另一个是grep
例如之前我们提到过的
具体用法看这里。
佳节又重阳,玉枕纱橱,半夜凉初透
东篱把酒黄昏后,有暗香盈袖。
莫道不消魂,帘卷西风,人比黄花瘦。
本文的参考文档主要出自《Linux程序设计》第四版第二章。
可以看做是更符合国人思路的精简版。
本文不会很长,建议全篇阅读。
什么是Shell
管道和重定向
重定向输出
重定向输入
管道
作为程序设计语言的shell
shell的语法
变量
环境变量
条件
控制结构
函数
命令
什么是Shell
shell是人和linux操作系统进行交互的工具。本质上也是一个跑在linux上的程序罢了。除此之外,它还可以执行脚本文件,从文件而不是人这里获取指令。管道和重定向
重定向输出
一个简单的例子ls -l > `lsout`.txt
默认情况下,上面这个命令会覆盖lsout.txt
若想在文件上追加
ls -l >> lsout.txt
更多的内容:其实一个程序的输出不止一个。比如还有标准错误输出。(也许你之前没有接触到过,但是这点也很重要)
kill -HUP 1234 >killout.txt 2>killerr.txt
kill如果给一个已经结束的进程发送HUP信号,那么将会报错。
>killout.txt表示将标准输出重定向到killout.txt这个文件。
2>killerr.txt表示将标准错误输出定向到killerr.txt这个文件。
2代表的是标准错误输出。
如果将两者都输出到同一个文件,那么可以这样写
kill -HUP 1234 >killout.txt 2>&1
&1的含义是标准输出的指向。
我们也可以丢弃掉输出的信息:
kill -1 1234 >/dev/null 2>&1
重定向输入
例如:#more自身也可以直接读取文件 more < killout.txt
管道
有些时候使用管道明显更方便:ps|sort|more
注意不要这样
cat mydata.txt|sort|uniq>mydata.txt
管道构建时,这些命令是同时进行的,uniq>mydata.txt会清空掉mydata.txt
作为程序设计语言的shell
和python等比较相似,比较简单的shell语句是可以直接在bash上运行的。例如:
#!/bin/sh #称之为glob通配符 for file in * do #如果在file中找到了'include' if grep -l include $file then echo $file fi done #退出 返回一个有意义的退出码 exit 0
接下来需要把脚本设置为可执行权限:
chmod +x mysh.sh
然后
./mysh.sh
加上
.是因为bash的环境变量PATH中没有当前路径。
shell的语法
变量
shit=shitshit fuck="fuckfuck" you=1+3 echo $shit,$fuck,$you
这就是shell的命名方法,创建变量时不需要,但在获取它的值的时候必须加,但在获取它的值的时候必须加。
上面三种变量都是多少?
都是字符串:
shitshit,fuckfuck,1+3
读取输入赋值
read shit
环境变量
变量名 | 说明 |
---|---|
$HOME | 当前用户家目录 |
$PATH | shell用来搜索命令的目录 |
$0 | 当前shell脚本名称 |
$# | 传递给脚本的参数个数 |
$$ | 进程PID |
变量名 | 说明 |
---|---|
$1,$2,$3 | 脚本程序的参数 |
$@ | 一个分割开的字符串 |
打印出所有的参数名称:
#!/bin/bash for i in $@ do echo $i done exit 0
当
./my.sh 1 2 3 1 2 3
条件
判断某一个文件是否存在:if test -f mysh.sh then echo shit you are here fi
或者这种:
if [ -f mysh.sh ] then echo shit fi
(是不是shell编程很累啊?相比之下python的方式就要友好得多,靠缩进来说明结构,不需要then fi do done这些语句。但是这么做肯定是由当年的一些限制在里边。python要到1989年才能发明出来~)
[ -f mysh.sh ]可以看做test命令的变种。除了进行文件测试外:
还可以有字符串、算术等。具体可以看这里。
控制结构
我们之前已经有提及到其控制结构了:if condition then statements elif statements else statements fi
for循环一般是字符串
for variable in values do statements done
但是这样很明显太弱了,for还可以用通配符来拓展:
#!/bin/bash for file in $(ls f*.sh) do #打印文件 lpr $file done exit 0
需要特别注意的是在ls f*.sh上加上$()
while语句:
while condition do statement done
朴素的密码验证
#!/bin/bash echo "print your password" read word while [ "$word" != "secret" ] do echo "Sorry,try again" read word done exit 0
你会注意到$word加了一个引号,这么做是为了防止如下情形:
当word为空时,则变成了[ !=”secret” ]
case语句:
case variable in pattern[|pattern]...) statements;; pattern[|pattern]...) statements;; esac
一个小栗子:
#!/bin/bash echo "yes or no?(y/n)" read yn case "$yn" in y|yes|ok) echo "confirmed!" echo "successfully";; n|no|n*) echo "canceled";; *) echo "you say what?";; esac exit 0
1.注意pattern其实是支持通配符的,*代表了一个字符串
2.注意一个case下可以有多条语句
函数
shell的函数可能看起来不怎么严谨。function_name(){ statements }
没有返回类型,没有参数类型。
我们只谈两三个简单的例子:
捕获返回结果
foo(){echo JAY;} ... result="$(foo)"
一个复杂的点的返回0或1的函数
#!/bin/bash yesno(){ echo "is your name $* ?" while true do echo -n "Enter yes or no:" read x case $x in y*) return 0;; n*) return 1;; *) echo "you say what ?" esac done } echo "原始参数是: $*" if yesno "$1" then echo "OK" else echo "Well..." fi exit 0
命令
我认为比较重要的有:exec命令
exit n命令
expr命令
之前说过,无论是单引号双引号还是都是字符串。
类似于
s=1+2这样得到的结果只是一个字符串
1+2
正确的用法是:
x=`expr 1 + 2` #或者 x=$(expr 1 + 2)
你是否注意到这个
$的作用?我们之前在for的用法中也用到过,如果忘记了请往回看看。
需要注意的是expr是一个命令,后面这个表达式每一个之间都有一个空格,这样命令才能正确识别。
如果我们要实现x的自加
x=$(expr $x + 1)
printf命令
基本形式是:
printf "format string" parameter1 parameter2...
示例
printf "%s %d \t%s" "Hi There" 15 people
“Hi There”之所以也有双引号是因为需要将其看做一个整体。这一技巧还会在很多地方看到。
trap
在Shell编程中比较常用的两个外部命令:
find
find [path] [options] [test] [actions]
find的具体指令请看这里。
另一个是grep
grep [options] PATTERN [FILES]
例如之前我们提到过的
grep -l include * #搜索当前目录下的所有带有"include"的文件名
具体用法看这里。
相关文章推荐
- shell, python中比较两个日期的先后
- xshell常用快捷键
- 运行脚本提示/bin/bash^M: bad interpreter: No such file or directory
- bat脚本如何自动执行 adb shell 以后的命令
- Xshell无法连接虚拟机中的Ubuntu
- bash shell 命令记录
- python执行shell命令的几种方法
- shell特殊变量 字符截取
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 常见处理文本的SHELL命令
- 用SHELL脚本把字符编码转换插到oralce
- 用SHELL脚本把字符编码转换插到oralce