我学shell编程2
- 利用mplayer中的mencoder来将y4m文件转换为yuv文件。
YUV4MPEG2这种文件格式是一种以头文件存储视频规格的未压缩视频序列。简单来说,在原始的yuv序列的起始和每一帧的头部都加入了纯文字形式的视频参数信息,包括分辨率、帧率、逐行/隔行扫描方式、高宽比(aspect ratio),以及每一帧起始的"FRAME "标志位。
(1)利用mencoder可以将y4m转换为yuv文件:
mencoder **.y4m -ovc raw -of rawvideo -vf format=i420 -o **.yuv
(2)mplayer 播放yuv和264文件
.yuv:
mplayer -demuxer rawvideo -rawvideo w=176:h=144 suzie_qcif.yuv
.264:
mplayer -fps 30 test.264
2. last命令用法
功能说明:列出目前与过去登入系统的用户相关信息。
语 法:last [-adRx][-f <记录文件>][-n <显示列数>][帐号名称...][终端机编号...]
补充说明:单独执行last指令,它会读取位于/var/log目录下,名称为wtmp的文件,并把该给文件的内容记录的登入系统的用户名单全部显示出来。
参 数:
-a 把从何处登入系统的主机名称或IP地址,显示在最后一行。
-d 将IP地址转换成主机名称。
-f <记录文件> 指定记录文件。
-n <显示列数>或-<显示列数> 设置列出名单的显示列数。
-R 不显示登入系统的主机名称或IP地址。
-x 显示系统关机,重新开机,以及执行等级的改变等信息。
3. if语句中判断多个条件的方法
if [ $a -lt 1 ] && [ $b -lt 2 ] then #do something elif [ $a -gt 3 ] || [ $b -gt 8 ] #do something fi | if [ $a -lt 1 -a $b -lt 2 ] then #do something elif [ $a -gt 3 -o $b -gt 8 ] #do something fi |
4. 删除空行(或者带有空格)
sed /^[[:space:]]*$/d filename 删除有空格的空行
sed s/[[:space:]]//g filename 删除空格
sed /^$/d filename 删除没有空格的空行
其他方法
grep: grep -v '^$' file
sed: sed '/^$/d' file 或 sed -n '/./p' file
awk: awk '/./ {print}' file
5. 颜色显示
如果要在shell终端显示颜色的话,需要采用ANSI 转义码。
首先,要控制转义格式,就必须使用选择图形再现转义码SGR,其格式是:
CSIn[;k]m
其中的m代表转义码,n和k表示要使用的显示控制。可以指定一个,也可以指定两个,然后中间使用分号隔开。
常用的显示控制参数主要包括3类:
- 效果控制代码:主要的控制代码如下:
代码 | 描述 | 代码 | 描述 |
0 | 重置为普通模式 | 4 | 使用单下划线(可以) |
1 | 设置为强亮度(在bash中是加粗) | 5 6 | 使用慢闪烁(没有反应) 使用快闪烁 |
2 | 设置为弱亮度(在bash中可以) | 7 | 背景、前景颜色反转(可以) |
3 | 使用斜体(这个在bash中不起作用) | 8 | 将前景色设置为背景色(可以) |
- 前景控制代码和背景控制代码
前景和背景都是使用两位数代码,前景是以3开头,背景是以4开头,第二位数字代表的是颜色。如下:
代码 | 颜色 | 代码 | 颜色 |
0 | 黑色 | 4 | 蓝色 |
1 | 红色 | 5 | 洋红色 |
2 | 绿色 | 6 | 青色 |
3 | 黄色 | 7 | 白色 |
给出一个例子:
CSI31;40m代表前景是红色,背景设为黑色
具体在代码的实现中CSI字符通常是一个两字符序列:"ESC ASCII值",然后后跟左方括号。而对于ESC键我们可以采用不同的方式:
- 使用Ctrl-V组合键后跟ESC键就可以得到"^[",而这个就代表ESC键。
- 使用ESC对应的转义字符\e或\033(这两个是一回事,因为shell中使用\0xx来代表ASCII值,而xx是字符对应的ASCII码值的八进制,ESC对应的八进制ASCII值是033)
这两种不同的方式中需要注意的一点是第一种方式使用echo的时候不需要加-e,而第二种方式需要加上-e
具体的代码如下:
echo "^[[31;40mtest^[[0m"
echo -e "\e[31;40mtest\\033[0m"
所以,我们也可以看到使用\e更方便一些
还有一点是,当使用cat等命令显示脚本的内容的时候,第一种方式也会做出解释(产生效果),而第二种这不会。我们可以根据自己的需求进行选择。
另外,这种显示颜色的方式还可以使用在C语言中的printf函数中。
int main(){
printf("\e[32;1m%s\e[0m\n","hello world");
return 0;
}
6. 标点符号替换
将name中的中文标点替换成英文标点:
name2=$(echo $name|sed -e 's/。/\./g' \ -e 's/,/,/g' \ -e 's/ //g' \ -e 's/;/\;/g' \ -e 's/?/?/g' \ -e 's/:/\:/g' \ -e "s/'/\'/g" \ -e "s/'/\'/g" \ -e 's/"/\"/g' \ -e 's/"/\"/g' \ -e 's/《/\</g' \ -e 's/》/\>/g' \ -e 's/——/_/g' \ -e 's/【/[/g' \ -e 's/】/]/g' \ -e 's/(/\(/g' \ -e 's/)/\)/g' \ -e 's/……/^/g' \ -e 's/!/\!/g' \ -e 's/『/\{/g' \ -e 's/』/\}/g' \ -e 's/¥/\$/g') |
这儿需要注意的就是对于要对单引号的操作中sed命令要使用双引号引起来。
7. rpm 软件包管理系统。
redhat类的linux系统中都是使用rpm来进行软件包的管理。其基本常用的方式主要有:
-ivh 安装软件包
-Uvh 升级软件包
-ef 卸载软件包
-q 查询软件包是否被安装
-qi 获得被安装软件包的信息
-ql 列出软件包中的文件
-qa 列出所有被安装的rpm软件包
8. linux中的账户管理
(1)密码体系
用户口令文件——/etc/shadow
在Linux系统中通常使用影子口令机制(Shadow Password),用户的身份信息被存放在/etc/passwd文件中,用户的口令信息加密后保存在另一个文件/etc/shadow中,并只设置root账号的可读属性,因而大大提高了系统的安全性能。
(2)setuid和setgid
用户存储用户信息的/etc/passwd文件只有超级用户才能进行修改,而用于存储用户口令的文件/etc/shadow甚至只有超级用户才可以访问。只有在普通用户执行passwd命令的时候,能够读取和修改/etc/passwd和/etc/shadow文件,才能使普通用户修改自己的口令。为了解决在用户修改口令时,文件系统存取权限矛盾,Linux给/usr/sbin/passwd命令设置了setuid属性。
setuid是一种文件的拥有者具备的特殊属性,它使得被设置了setuid位的程序无论被哪个用户启动,都会自动具有文件拥有者的权限,在Linux中典型拥有setuid属性的文件就是/usr/bin/passwd程序,见下图。通常setuid属性只会设置在可执行的文件上,因为尽管理论上可以给不可执行的文件加上setuid属性,但是这样做通常是没有意义的。
文件属性中的s占据的位即为setuid位,"s"代表对应的文件被设置了setuid属性,因为passwd程序的拥有者是超级用户root,因此passwd程序执行的时就自动获取了超级用户的权限,所以无论是哪个用户执行了passwd程序都可以修改系统的口令文件。
9. bash中变量引用时的注意事项
(1)bash中,变量不以$打头的几种情况:
" "称为弱引用(weak quoting/partial quoting),
' '称为强引用(strong quoting/full quoting)。
变量在" "中,可以被解释,而在' '中,只是作为字符串。
(2)区分Make和Bash中的变量
Bash中,变量赋值=左右不能有空格,而Make中可以有。
Bash中变量的引用是$var或${var},而Make中则是$(var)或${var},Make中只有单个字符串的变量可以是$var。
Bash中如果写作VAR =var,则会执行命令VAR,并赋予VAR命令以=var参数;
如果写作VAR= var,则会执行命令var,并赋予var命令以VAR("")环境变量。
10. linux中对于命令行参数的处理方法
在bash中,可以用以下三种方式来处理命令行参数,每种方式都有自己的应用场景。
1.直接处理,依次对$1,$2,...,$n进行解析,分别手工处理;
2.getopts来处理,单个字符选项的情况(如:-n 10 -f file.txt等选项);
3.getopt,可以处理单个字符选项,也可以处理长选项long-option(如:--prefix=/home等)。
总结:一般小脚本手工处理也许就够了,getopts能处理绝大多数的情况,getopt较复杂、功能也更强大。
处理命令行参数是一个相似而又复杂的事情,为此,C提供了getopt/getopt_long等函数,C++的boost提供了Options库,在shell中,处理此事的是getopts和getopt。注意getopts/getopt的区别:getopt是个外部binary文件,而getopts是shell builtin。
11. shell中字符串的操作处理
shell中对于字符串的处理
有几个比较有用的方面:
${#string} $string的长度
${string:position} 在$string中, 从位置$position开始提取子串
${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串
${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串
${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
12.shell中数学计算
(1)count=1;count=$[ $count+1 ]
(2) let i=i+1;
(3)(( i=i+1 ))
(4)i=$((i+1))
(5)var=1;var=`expr $var + 1`
((i=$j+$k)) 等价于 i=`expr $j + $k`
((i=$j-$k)) 等价于 i=`expr $j - $k`
((i=$j*$k)) 等价于 i=`expr $j \* $k`
((i=$j/$k)) 等价于 i=`expr $j / $k`
注意:expr使用规则:用空格隔开每个项。
用 \ (反斜杠) 放在 shell 特定的字符前面。
对包含空格和其他特殊字符的字符串要用引号括起来
13. shell中数组的使用方法:
shell中数组的声明,a=(1 2 3 4 5) #一对括号表示是数组,数组元素用"空格"符号分割开。
得到数组长度:echo ${#a[@]} #用${#数组名[@或*]} 可以得到数组长度
获得某个数组元素:echo ${a[2]} #用${数组名[下标]} 下标是从0开始 下标是:*或者@ 得到整个数组内容
获得所有元素:echo ${a[*]}或echo ${a[@]}
赋值a[2]=33 #直接通过 数组名[下标] 就可以对其进行引用赋值,如果下标不存在,自动添加新一个数组元素
删除某个数组元素 unset a[2] #直接通过:unset 数组[下标] 可以清除相应的元素,不带下标,清除整个数据。
删除整个数组:unset a
14. 随机数获得方法:
Shell中对应的操作是:
- 利用系统内部变量$RANDOM:
echo $RANDOM
这样就会得到一个随机数
如果要得到某一范围内的随机数可以使用expr
如下,可以获取 1-5的随机数
choose=`expr $RANDOM % 5`
choose=`expr ${choose} + 1`
(2) 使用awk中的随机函数生成0-1随机数
awk 'BEGIN{srand();print rand()}'
不过这个是一次性的。上面的方法比较不错。
C语言中采用的方法:
- 如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h, 其值为2147483647。
如果要设定范围的话可以使用rand()%x
- 上面方法的随机数是一次性的。采用srand设定随机种子可以得到不同的随机数
srand((int)time(0));
for(int x=0;x<10;x++)
printf("%d\n",random(100));