下面小编给大家整理的shell 学习笔记(转)Unix系统,本文共8篇,欢迎阅读与借鉴!

篇1:shell 学习笔记Unix系统
bbs.chinaunix.net/forum/viewtopic.php?t=218853show_type=new(+三问) 假如我需要在 command line 中⑦@些保留字元的功能P]的,就需要 quoting 理了, 在 bash 中,常用的 quoting 有如下三N方法: * hard quote:' ' (我),凡在 har
bbs.chinaunix.net/forum/viewtopic.php?t=218853&show_type=new(+三问)假如我需要在 command line 中⑦@些保留字元的功能P]的,就需要 quoting 理了,
在 bash 中,常用的 quoting 有如下三N方法:
* hard quote:' ' (我),凡在 hard quote 中的所有 meta. 均被P]。
* soft quote: “ ” (p引),在 soft quoe 中大部份 meta. 都被P],但某些t保留(如 $ )。(]二)
* escape : \ (反斜),只有o接在 escape (跳字符)之後的我 meta. 才被P]。
( ]二:在 soft quote 中被豁免的具w meta. 清危我不完全知道,
有待大家a充,或透^作戆lF及理解。 )
原文转自:www.ltesting.net
篇2:linux Shell学习笔记第二天
作者: 字体:[增加 减小] 类型:
今天做笔记稍微整理了下,但是避免不了出现错误,如果有错误麻烦大家给提出,本文最后将会共享今天的三个脚本文件,
变量
获取本机主机名
#hostname
获取本系统版本号
#uname -r
获取cpu类型
获取cpu的工作频率
cat /proc/cpuinfo
获取内存使用情况
#free -m
获取硬盘使用情况
#df
变量类型及变量操作
本地变量(一般所指)
本地变量只存在用户当前shell中,当用户退出当前shell或开器一个新的shell,所设置的变量将会不存在
设置变量
#变量名=变量值
显示变量
#echo ${变量名}
假设a=1 显示则 echo ${a}
环境变量(用的非常少)
环境变量用于所有用户进程(经常称为子进程)。登录进程称为父进程。Shell中执行的用户进程均称为子进程。不像本地变量,环境变量可用于所有子进程,这包括编辑器、脚本和应用
环境变量在用户注销时会消失,因此最好在$HOME/.bash_profile(/etc/profile)文件里直接定义
位置变量(跟脚本和函数有很大的关系)
位置变量表示$0,$1… …$9 (只有9个)
$0
$1
$2
$3
$4
$5
$6
$7
$8
$9
脚本名字
A
B
C
D
E
F
G
H
I
$0=当前脚本名称
向脚本中使用位置参数
向系统命令传递参数
特殊变量
$# 传递到脚本的参数列表个数
$* ($@) 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
引用的必要性
变量操作中,脚本执行变量赋值时最容易犯的一个错误就是引用错误
例:echo abc *
echo abc ‘*‘
echo Hit the star button to exit *
引用的方式
双引号(“)(需要排除以下几个)
使用双引号可以引用除$、`、\、字符外的任意字符或字符串
单引号(‘)(比较霸道,任何都可以转成字符)
与双引号类似,不同的是shell会忽略任何引用值,
换句话说,如果屏蔽了其特殊含义,会将引号里的所有字符,都作为一个字符串。
反引号(`)(将括号内的当作命令来执行)
用于设置系统命令的输出到变量。
shell将反引号中的内容作为一个系统命令,并执行其内容
反斜杠(\)
如果一个字符有特殊含义,反斜线防止shell误解其含义,即屏蔽其特殊含义。
下述字符包含有特殊意义:& * + ^ $ ` ” | ?
脚本实例
Hello.sh
#!/bin/bash
#This is the first script
echo “Hello,World!”
执行:
chmod u+x Hello.sh
./Hello.sh
var.sh
#!/bin/bash
echo $1
echo $2
echo $3
echo $4
echo $5
echo $6
echo $7
echo $8
echo $9
echo $10
#!/bin/bash
echo Ce “hostname\t `hostname`”
echo Ce “OScore\t `uname -r`”
echo Ce “CPUInfo\t `grep “model name” /proc/cpuinfo|awk CF: ‘{print $2}‘`”
ehco Ce “CPUMHz\t `grep “MHz” /proc/cpuinfo | awk CF: ‘{print $2}‘`”
echo Ce “MEMTotal\t `free | awk ‘$1=”Mem:”{print $2}‘`”
echo Ce “DiskInfo\t `df | grep dev |awk ‘{print $1 $2}‘`”
回顾:
脚本的结构与运行
变量的类型及用法
环境变量
本地变量
参数变量
特殊变量
变量赋值时的引用方法
篇3:linux Shell学习笔记第三天
作者: 字体:[增加 减小] 类型:转载
今天收获还是比较多的, 半个小时的教程看了将近3个小时
第三天:条件选择
大 纲
应用实例分析
条件测试
if…else…fi
case…in…esac
实现功能菜单:
执行脚本后
按1,显示当前时间
按2,显示CPU负载
按3,显示剩余内存
按0,退出脚本
按其他字符,提示超出选择范围后退出
分析步骤。
#date +%T
uptime awk截取
free Cm
条件测试格式
#test Coption obj
#[ -option obj ]
返回结果
表达式内容测试结果是真的
表达式内容测试结果是假的
测试的对象分类
执行结果(执行成功或失败)
文件(文件是否存在等)
文本(是否一致)
数字(数值比较)
条件测试的选项
选项作用-d目录-e是否存在-f是否是普通文件-s文件大小是否等于0-r是否可读-w是否可写-x是否可执行
逻辑操作符号
选项
作用-a
与操作-o
或操作!
非操作实例:
#test Ce /etc/passwd Ca Ce /etc/shadow 中间是a与操作,则都为0才得0
#test Ce /etc/passwd Co Ce /etc/groups 中间是o或操作,则有一真则真0
字符串操作符
== 两个字符串相等
!= 两个字符串不相等
-z 空字符串
-n 非空字符串
实例:
#test Cz $LOGNAME
#echo $LOGNAME
#echo $?
数值比较操作符
符号
说明-eq
等于-ne
不等于-gt
大于-lt
小于-ge
大于等于-le
小于等于if…else…fi 条件选择
if控制结构的基本格式:
if条件 #判断开始 可以是命令,也可以是test语句
then #如果条件为真 反值真0则执行
命令1 #执行命令1
else #如果条件为假 反值假1则执行
命令2 #执行命令2
fi #判断结束
实例(if…else…fi)1
inputtest.sh
#!/bin/bash
#input test
echo Cn “Enter your name:”
read name
#did the user just hit return
if [ “${name}” == “” ]
then
echo “You did not enter any information”
else
echo “Your name: ${name}”
fi
实例(if…else…fi)2
filecopy.sh
#!/bin/bash
#file copy
if cp /etc/passwd passwd.bak 2>/dev/null 2>/dev/null 丢掉错误提示
then
echo “Good Copy!”
else
echo “`basename $0`: error,could not copy”
fi
if…else…fi的嵌套 (两层的嵌套)
if 条件1;then
if 条件2;then
命令1
else
命令2
else
if条件3;then
命令3
else
命令4
fi
case…in…esac条件选择 (比较灵活的方式)
case语句多用于较多分支判断
case格式: (多种模式,只匹配和variable相等的模式)
case variable in
模式1)命令1…;;
模式2)命令2…;;
esac
匹配模式
* 匹配任意字符
? 匹配任意单字符
[] 匹配字符范围
case…in.esac实例1
#!/bin/bash
#case select
echo Cn “enter a number from 1 to 5:”
read NUM
case $NUM in
1) echo “you select 1″ ;;
2) echo “you select 2″ ;;
3) echo “you select 3″ ;;
4) echo “you select 4″ ;;
5) echo “you select 5″ ;;
*) echo “basename $This is not between 1 and 5″
esac
case…in.esac实例2
题目是:学生的考试成绩是0-100分,在85以上的要提示you are the best!,在70-84显示you get a good mark! ,在60-74的显示come on!,60分以下显示You must study hard!
#!/bin/bash
echo Cn “please input your mark:”
read mark
case $mark in
100|9[0-9]|8[5-9]) echo “you are the best!”;; 100、90-99、85-89
8[0-4]|7[0-9]) echo “you get a good mark!”;; 80-84、70-79
7[0-4]|6[0-9]) echo “come on!”;; 70-74、60-69
[0-5][0-9]) echo “You must study hard!”;; 00-59
esac
解决今天的问题
使用if…else…fi的方式对输入的变量进行判断,
在每个判断的分支上执行相应的语句。
menu.sh
#!/bin/bash
clear
echo “――――――Cmenu―――――C”
echo “1) Show Time”
echo “2) CPU load”
echo “3) Memory free”
echo “0) Exit”
echo “――――――――――――――C”
echo -n “Enter you chose [0-3]:”
read NUM
if [ ${NUM} -lt 0 -o ${NUM} -gt 3 ]
then
echo “This is not between 0-3.”
else
if [ “${NUM}” == “1” ]
then
echo “`date +%T`”
else
if [ “${NUM}” == “2” ]
then
echo “`uptime | awk -F ‘[,:]‘ ‘{print $7}‘`”
else
if [ “${NUM}” == “3” ]
then
echo “`free -m | awk ‘$1==”Mem:”{print $4}‘`”
else
exit
fi
fi
fi
fi
本节课回顾:
条件测试的类型
文件测试
文本测试
数值测试
逻辑测试
if…else…fi条件选择结构
case…in…esac
课后测试
1、修改menu.sh 采用非菜单式,参数传递方式来进行选择。 例如 #./menu.sh 1 输出时间
2、使用case方式来实现该菜单选择方式
Sudu答案:(难免会有错误,但是可以实现成功)
1、修改menu.sh后得出
#!/bin/bash
if [ $1 -lt 0 -o $1 -gt 3 ]
then
echo “This is not between 0-3.”
else
if [ “$1” == “1” ]
then
echo “`date +%T`”
else
if [ “$1” == “2” ]
then
echo “`uptime | awk -F ‘[,:]‘ ‘{print $7}‘`”
else
if [ “$1” == “3” ]
then
echo “`free -m | awk ‘$1==”Mem:”{print $4}‘`”
else
exit
fi
fi
fi
fi
2、 #!/bin/bash
clear
echo “――――――Cmenu―――――C”
echo “1) Show Time”
echo “2) CPU load”
echo “3) Memory free”
echo “0) Exit”
echo “――――――――――――――C”
echo -n “Enter you chose [0-3]:”
read NUM
case $NUM in
1) date +%T;;
2) uptime | awk -F ‘[,:]‘ ‘{print $7}‘;;
3) free -m | awk ‘$1==”Mem:”{print $4}‘;;
0) exit ;;
*) echo “This is not between 0-3.” ;;
esac
今天收获还是比较多的。 半个小时的教程看了将近3个小时。
虽然说if…else…fi比较容易理解,但是用case感觉简单很多,呵呵,看个人喜好吧。
每天看来看一节教程就足够了。 看多了头也会晕的。 呵呵。 继续学习吧~
篇4:linux Shell学习笔记第一天
作者: 字体:[增加 减小] 类型:
从昨天开始看Shell的教程到现在已经两天了,现在把记录的笔记发出来,目前是很乱,主要是留给自己看看,后续等差不多了会整理统一发布出来。
以下是Shell学习1-2天学习笔记
――――――――-我是分隔符―――――――――
硬件去执行, 内核与硬件之间进行操作。
命令解析器。
shell脚本的组成元素
系统命令
文本处理工具(sort、grep、sed、awk…)
变量
条件判断
环循结构
函数
Shell Scripts Center(SSC)
―――――――――――――――――――――――――――-
非负Grep / awk
几天。 统计Wc
Sort 排序 sort|head / sed
字段处理 awk
数据区域判断 awk |wc
显示文本: echo [选项] 文本
-n 不要自动换行
-e 解析转义符
a 发出警告音
c 最后不加上换行符号
f 换行
r 回车
彩色文本
Echo Ce “33[40;35m….]”
echo “Hello,world”
echo Ce “33[40;35mHell,world33[0m“
sort [选项]输入文件
-o 输出文件
-d 按字典顺序排序 a-z
-n 按数字大小输出 0-9
-r 逆序输出 z-a 9-0
-k 指定分类是域上的数字分类
-t 域分割符;用非空格或tab键分割域
more /etc/passwd 分页显示
sort Cd /etc/passwd|more 中间的|是反倒符号。 将前面处理的交给后面处理 先排序。后分页显示
sort Ck3 Cn Cr Ct: /etc/passwd|more
从大到小
wc [参数] [文件名]
-c 统计字符数量
-l统计行数
-w 统计单词数量 空格区分
diff [选项] 文件/目录 文件/目录
diff /etc/passwd /etc/passwd.bak
-q 仅显示有无差异,不显示详细的信息
-c 显示全部内文,并标出不同之处。
-b 不检查空格字符的不同
-B 不检查空白行
-r 比较子目录中的文件。
grep 搜索匹配 支持正则表达式
grep
-c 只打印匹配模式的行编号记数
-I 在匹配文本时忽略大小写
-n 在每行前显示其行编号
-v 逆向输出,打印不匹配的行
-f file 要匹配的字符串列表在filezhong
grep ‘[Tt]his‘ file1.txt 设置大小写
grep ‘^[^#]‘ file2.txt 不匹配行首
grep “s…n” file3.txt 匹配任意字符
sed 行编辑命令
s 替代
i 插入
a 附加
d 删除全部匹配的行
D 删除首次匹配的行
sed可以做什么(”行”为基础)
删除
改变
添加
插入
替换
示例
sed Cn ‘1,4p‘ /etc/passwd p是打印 -n 不显示原文件 打印1-4行
sed ‘/80/D‘ file.txt 首次出现80的行进行删除
sed ‘s/var/usr/g‘ file.txt 将所有的var替换成usr g代表所有
sed ‘50,$s/help/man/g‘ file.txt 替换从50行到最后一行的help替换为man 前49不管
awk 可以处理列,也可以处理行,可以定位到第几行,第几列
awk [选项] ‘awk脚本‘ 输入文件
-F fs 使用fs作为输入记录的字段分隔符 = sort Ct
-f filename 从文件filename读取awk_script(awk脚本)
-v var=value 为awk_script. 设置变量
awk的内置变量
变量功能默认FS =大写F输入字段分隔符空格或tabRS输入记录分隔符换行OFS =out FS输出字段分隔符空格或tabORS输出记录分隔符换行NF 常用当前记录非空字段的编号NR 常用从所有文件读入的记录号
示例
awk CF : ‘{print NR,$1,$2}‘ /etc/passwd
awk CF : ‘{print NR,$1,$NF}‘ /etc/passwd $NF 提取最后一行
awk CF : ‘NR%10==5{PRINT nr,$0}‘ /etc/passwd NR= 当前处理的行数 除10求余=5打印当前的行数,进行输出 $0 整行输出,比如5、15、25 打印出来
awk CF : ‘NR==8,NR==13 {print NR,$0}‘ /etc/passwd 指定8行和13行,
awk工作原理(工具)
$NF $NR $1 第一列 $2 第二列 $0 一整行
实际测试
awk CF: ‘{print $1,$3}‘/etc/passwd
awk CF: ‘{print $1,$NF}‘/etc/passwd
awk CF: ‘{print NR,$1,$NF}‘/etc/passwd NR行号
awk CF: ‘NR==5,NR==8{print NR,$1,$NF}‘/etc/passwd 指定5-8行
awk CF: ‘NR%10==5{print NR,$1,$NF}‘/etc/passwd 除10求余
课程示例测试
1、grep Cv “-” file.txt 去除所有带负号的数据 -v显示没有的 没有的话则显示只有-的
2、wc -l file.txt显示所有行数 grep Cv “-” file.txt |wc Cl 统计所有没有负数的
3、sort Cn Cr Ck4 file.txt |sed Cn ‘1p‘ 排序第四列 没有分隔符(即空格),-n数字 Cr 从大到小 sed管道 显示第一行 sed Cn不显示原文件
sort Cn Cr Ck4 file.txt |head -1 读取第一个数据 head 第一行
4、awk ‘{if($NF>3){print $0}}‘ file.txt NF 最后一列大于3 则打印一整行
5、awk ‘{if($4>0,&&$4<15){print $0}}‘ file.txt 列出第四列 大于0小于15 输出整行
awk ‘{if($4>0,&&$4<15){print $0}}‘ file.txt |wc Cl 显示行数
练习:
grep和awk
awk ‘{if($1>01011){[print $0}}‘file.txt
2、
处理命令回顾:
统计文本 wc
文本排序 sort
文本/目录对比 diff
在文件中查找关键行 grep / sed
在行文本中添、删、改 sed
在列文本中显示指定列 awk
在列文本中进行计算 awk
在列文本进行条件选择 awk
篇5:shell脚本学习笔记简介及基本格式
shell简介
shell英文原意是壳,贝壳的意思,在linux,unix系统中的shell是一个接受用户指令的的命令行界面。当shell执行程序时,它会请求内核启动新的进程,在该进程里执行当前序,具体的实现是shell调用fork函数产生新进程,在新进程里调用exec函数加载指定程序。shell可以执行二进制可执行文件(elf文件),或者是脚本文件(具备可执行权限)。 对于脚本文件的处理,shell会启动一个新的shell来处理。
shell脚本基本格式
因为shell的实现由很多种,linux常用的默认的shell是bash,但还有很多其他shell,如b shell, c shell等。所以我们在编写shell脚本的时候需要一种机制能搞告知内核,我们需要用到哪种shell来执行我们的脚本,
shell脚本使用脚本里的第一行来标识具体使用哪种shell。
[html]
#! /bin/bash
所有的shell脚本都以上面一行作为开始。脚本以#!作为开始,后面跟的是解释器的完整路径,路径后面还可以跟着参数,内核会根据相应的参数调用解释器。 我们编写一个简单地脚本程序nusers.sh,该脚本显示出当前登录系统的用户数量。
[html]
#! /bin/bash
who | wc -l
who命令会打印当前登录的用户的相关信息,通过管道 | 将结果传送给wc程序处理,wc -l 会打印出who命令输出信息的行数(who命令会将每个用户的信息用一行来显示)也就是用户的数量。
篇6:Linux shell命令学习笔记(一)linux操作系统
本文章来给大家介绍一下我自己学习linux的笔记,希望本方法对各位同学会有所帮助哦,
获取服务器IP的Shell 脚本:
代码如下复制代码#!/bin/bash
ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' |cut -d: -f2 | awk '{ print $1}'
下载整站
wget -mk www.111cn.net
判断文件的存在与否
代码如下复制代码#!/bin/bashif [ ! -f /root/log.l ]
then echo ”log.l note exist“
fi
常用语法
while 语句
代码如下复制代码#!/bin/bashecho ”enter passwd“
read passwd
while [ $passwd != ”iterse“ ];do
echo ”sorry try again“
read passwd
done
for 语句
代码如下复制代码#! /bin/bashfor i in a b c; do
echo ”$in“
done
case 语句
代码如下复制代码#! /bin/sh
echo ”Enter a number“
read number
case $number in
1)
echo ”you number is 1“
;;
2)
echo ”yo number is 2“
;;
*)
exit 1
;;
esac
if else elif fi
代码如下复制代码#! /bin/sh
echo ”Is it morning? Please answer yes or no.“
read YES_OR_NO
if [ ”$YES_OR_NO“ = ”yes“ ]; then
echo ”Good morning!“
elif [ ”$YES_OR_NO“ = ”no“ ]; then
echo ”Good afternoon!“
else
echo ”Sorry, $YES_OR_NO not recognized. Enter yes or no.“
exit 1
fi
exit 0
篇7:Linux服务器Shell编程学习笔记linux操作系统
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口,它接收用户输入的命令并把它送入内核去执行。实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。
Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit、kedit、emacs、vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行):
代码如下复制代码#!/bin/sh
...注意:最好使用“!/bin/bash”而不是“!/bin/sh”,如果使用tc shell改为tcsh,其他类似。
符号#!用来告诉系统执行该sell脚本的程序,本例使用/bin/sh。编辑结束并保存后,如果要执行该shell脚本,必须先使其可执行:
chmod +x filename此后在该shell脚本所在目录下,输入 ./filename 即可执行该shell脚本。
Shell里的一些特殊符号
a []
shell离得函数
如果你写过比较复杂的shell脚本,就会发现可能在几个地方使用了相同的代码,这时如果用上函数,会方便很多。函数的大致样子如下:
代码如下复制代码functionname{
# inside the body $1 is the first argument given to the function
# $2 the second ...
body
}
你需要在每个脚本的开始对函数进行声明。
下面是一个名为xtitlebar的shell脚本,它可以改变终端窗口的名称。这里使用了一个名为help的函数,该函数在shell脚本中使用了两次:
代码如下复制代码#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat << HELP
xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] ”string_for_titelbar“
OPTIONS: -h help text
EXAMPLE: xtitlebar ”cvs“
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
[ -z ”$1“ ] && help
[ ”$1“ = ”-h“ ] && help
# send the escape sequence to change the xterm titelbar:
echo -e ”33]0;$107“
#在shell脚本中提供帮助是一种很好的编程习惯,可以方便其他用户(和自己)使用和理解脚本。
命令行参数
我们已经见过$* 和 $1, $2 … $9 等特殊变量,这些特殊变量包含了用户从命令行输入的参数。迄今为止,我们仅仅了解了一些简单的命令行语法(比如一些强制性的参数和查看帮助的-h选项)。 但是在编写更复杂的程序时,您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号,后面再加上参数值 (比如文件名)。
有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子无疑是一个不错的方法。
代码如下复制代码#!/bin/sh
help()
{
cat << HELP
This is a generic command line parser demo.
USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2
HELP
exit 0
}
while [ -n ”$1“ ]; do
case $1 in
-h) help;shift 1;; # function help is called
-f) opt_f=1;shift 1;; # variable opt_f is set
-l) opt_l=$2;shift 2;; # -l takes an argument ->shift by 2
--) shift;break;; # end of options
-*) echo ”error: no such option $1. -h for help“;exit 1;;
*) break;;
esac
done
echo ”opt_f is $opt_f“
echo ”opt_l is $opt_l“
echo ”first arg is $1“
echo ”2nd arg is $2“
你可以这样运行该脚本:
代码如下复制代码cmdparser -l hello -f -- -somefile1 somefile2
返回结果如下:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2
这个shell脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数。
shell脚本示例
一般编程步骤
现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。写一个框架脚本(framework.sh),该shell脚本包含了大多数脚本需要的框架结构,是一个非常不错的主意。这样一来,当我们开始编写新脚本时,可以先执行如下命令:
代码如下复制代码cp framework.sh myscript
然后再插入自己的函数。
让我们来看看如下两个示例。
二进制到十进制的转换
脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子:
代码如下复制代码#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat << HELP
b2d -- convert binary to decimal
USAGE: b2d [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2d 111010
will return 58
HELP
exit 0
}
error()
{
# print an error and exit
echo ”$1“
exit 1
}
lastchar()
{
# return the last character of a string in $rval
if [ -z ”$1“ ]; then
# empty string
rval=”“
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n ”$1“ | sed 's/ //g' | wc -c `
# now cut out the last char
rval=`echo -n ”$1“ | cut -b $numofchar`
}
chop()
{
# remove the last character in string and return it in $rval
if [ -z ”$1“ ]; then
# empty string
rval=”“
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n ”$1“ | wc -c | sed 's/ //g' `
if [ ”$numofchar“ = ”1“ ]; then
# only one char in string
rval=”“
return
fi
numofcharminus1=`expr $numofchar ”-“ 1`
# now cut all but the last char:
rval=`echo -n ”$1“ | cut -b -$numofcharminus1`
#原来的 rval=`echo -n ”$1“ | cut -b 0-${numofcharminus1}`运行时出错.
#原因是cut从1开始计数,应该是cut -b 1-${numofcharminus1}
}
while [ -n ”$1“ ]; do
case $1 in
-h) help;shift 1;; # function help is called
--) shift;break;; # end of options
-*) error ”error: no such option $1. -h for help“;;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z ”$1“ ] && help
binnum=”$1“
binnumorig=”$1“
while [ -n ”$binnum“ ]; do
lastchar ”$binnum“
if [ ”$rval“ = ”1“ ]; then
sum=`expr ”$weight“ ”+“ ”$sum“`
fi
# remove the last position in $binnum
chop ”$binnum“
binnum=”$rval“
weight=`expr ”$weight“ ”*“ 2`
done
echo ”binary $binnumorig is decimal $sum“
#该shell脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..),比如二进制”10″可以这样转换成十进制:
代码如下复制代码0 * 1 + 1 * 2 = 2
为了得到单个的二进制数我们是用了lastchar 函数,
该函数使用wc –c计算字符个数,然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。
文件循环
你可能有这样的需求并一直都这么做:将所有发出邮件保存到一个文件中。但是过了几个月之后,这个文件可能会变得很大以至于该文件的访问速度变慢;下 面的shell脚本 rotatefile 可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为outmail)为outmail.1,而原来的outmail.1就变成了 outmail.2 等等…
代码如下复制代码#!/bin/sh
# vim: set sw=4 ts=4 et:
ver=”0.1“
help()
{
cat << HELP
rotatefile -- rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1[BR]
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
}
error()
{
echo ”$1“
exit 1
}
while [ -n ”$1“ ]; do
case $1 in
-h) help;shift 1;;
--) break;;
-*) echo ”error: no such option $1. -h for help“;exit 1;;
*) break;;
esac
done
# input check:
if [ -z ”$1“ ] ; then
error ”ERROR: you must specify a file, use -h for help“
fi
filen=”$1“
# rename any .1 , .2 etc file:
for n in 9 8 7 6 5 4 3 2 1; do
if [ -f ”$filen.$n“ ]; then
p=`expr $n + 1`
echo ”mv $filen.$n $filen.$p“
mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f ”$filen“ ]; then
echo ”mv $filen $filen.1“
mv $filen $filen.1
fi
echo touch $filen
touch $filen
这个shell脚本是如何工作的呢?在检测到用户提供了一个文件名之后,首先进行一个9到1的循环;文件名.9重命名为文件名.10,文件名.8重 命名为文件名. 9……等等。循环结束之后,把原始文件命名为文件名.1,同时创建一个和原始文件同名的空文件(touch $filen)
脚本调试
最简单的调试方法当然是使用echo命令。你可以在任何怀疑出错的地方用echo打印变量值,这也是大部分shell程序员花费80%的时间用于调试的原因。Shell脚本的好处在于无需重新编译,而插入一个echo命令也不需要多少时间。
shell也有一个真正的调试模式,如果脚本”strangescript”出错,可以使用如下命令进行调试:
代码如下复制代码sh -x strangescript7
上述命令会执行该脚本,同时显示所有变量的值。
shell脚本中还有一个不执行脚本只检查语法的模式,命令如下:
代码如下复制代码sh -n your_script
这个命令会返回所有语法错误。
我们希望你现在已经可以开始编写自己的shell脚本了,尽情享受这份乐趣吧!
篇8:linux中Bash shell学习笔记linux操作系统
今天看到一站长写得非常不错的一篇关于Bash shell速成的学习笔记,下面我把文章转载并整理了一些其它相关的内容,希望给大家带来帮助,
BASH 的基本语法
•最简单的例子 —— Hello World www.111cn.net !
•关于输入、输出和错误输出
•BASH 中对变量的规定(与 C 语言的异同)
•BASH 中的基本流程控制语法
•函数的使用
2.1 最简单的例子 —— Hello World!
几乎所有的讲解编程的书给读者的第一个例子都是 Hello World 程序,那么我们今天也就从这个例子出发,来逐步了解 BASH。
用 vi 编辑器编辑一个 hello 文件如下:
#!/bin/bash
# This is a very simple example
echo Hello World
这样最简单的一个 BASH 程序就编写完了。这里有几个问题需要说明一下:
一,第一行的 #! 是什么意思
二,第一行的 /bin/bash 又是什么意思
三,第二行是注释吗
四,echo 语句
五,如何执行该程序
#! 是说明 hello 这个文件的类型的,有点类似于 Windows 系统下用不同文件后缀来表示不同文件类型的意思(但不相同)。Linux 系统根据 ”#!“ 及该字串后面的信息确定该文件的类型,关于这一问题同学们回去以后可以通过 ”man magic“命令 及 /usr/share/magic 文件来了解这方面的更多内容。在 BASH 中 第一行的 ”#!“ 及后面的 ”/bin/bash“ 就表明该文件是一个 BASH 程序,需要由 /bin 目录下的 bash 程序来解释执行。BASH 这个程序一般是存放在 /bin 目录下,如果你的 Linux 系统比较特别,bash 也有可能被存放在 /sbin 、/usr/local/bin 、/usr/bin 、/usr/sbin 或 /usr/local/sbin 这样的目录下;如果还找不到,你可以用 ”locate bash“ ”find / -name bash 2>/dev/null“ 或 ”whereis bash“ 这三个命令找出 bash 所在的位置;如果仍然找不到,那你可能需要自己动手安装一个 BASH 软件包了。
第二行的 www.111cn.net ”# This is a ...“ 就是 BASH 程序的注释,在 BASH 程序中从“#”号(注意:后面紧接着是“!”号的除外)开始到行尾的多有部分均被看作是程序的注释。的三行的 echo 语句的功能是把 echo 后面的字符串输出到标准输出中去。由于 echo 后跟的是 ”Hello World“ 这个字符串,因此 ”Hello World“这个字串就被显示在控制台终端的屏幕上了。需要注意的是 BASH 中的绝大多数语句结尾处都没有分号。
如何执行该程序呢?有两种方法:一种是显式制定 BASH 去执行:
$ bash hello 或
$ sh hello (这里 sh 是指向 bash 的一个链接,“lrwxrwxrwx 1 root root 4 Aug 20 05:41 /bin/sh ->bash”)
或者可以先将 hello 文件改为可以执行的文件,然后直接运行它,此时由于 hello 文件第一行的 ”#! /bin/bash“ 的作用,系统会自动用/bin/bash 程序去解释执行 hello 文件的:
$ chmod u+x hello
$ ./hello
此处没有直接 “$ hello”是因为当前目录不是当前用户可执行文件的默认目录,而将当前目录“.”设为默认目录是一个不安全的设置。
需要注意的是,BASH 程序被执行后,实际上 Linux 系统是另外开设了一个进程来运行的。
2.2 关于输入、输出和错误输出
在字符终端环境中,标准输入/标准输出的概念很好理解。输入即指对一个应用程序 或命令的输入,无论是从键盘输入还是从别的文件输入;输出即指应用程序或命令产生的一些信息;与 Windows 系统下不同的是,Linux 系统下还有一个标准错误输出的概念,这个概念主要是为程序调试和系统维护目的而设置的,错误输出于标准输出分开可以让一些高级的错误信息不干扰正常的输出 信息,从而方便一般用户的使用。
在 Linux 系统中:标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕(上面的 std 表示 standard)。在 BASH 中使用这些概念时一般将标准输出表示为 1,将标准错误输出表示为 2。下面我们举例来说明如何使用他们,特别是标准输出和标准错误输出。
输入、输出及标准错误输出主要用于 I/O 的重定向,就是说需要改变他们的默认设置。先看这个例子:
$ ls >ls_result
$ ls -l >>ls_result
上面这两个命令分别将 ls 命令的结果输出重定向到 ls_result 文件中和追加到 ls_result 文件中,而不是输出到屏幕上,
”>“就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个 ”>“ 符号,即 ”>>“ 则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子:
$ find /home -name lost* 2>err_result
这个命令在 ”>“ 符号之前多了一个 ”2“,”2>“ 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在 err_result 文件中。大家可以设想一下 find /home -name lost* 2>>err_result 命令会产生什么结果?
如果直接执行 find /home -name lost* >all_result ,其结果是只有标准输出被存入 all_result 文件中,要想让标准错误输出和标准输入一样都被存入到文件中,那该怎么办呢?看下面这个例子:
$ find /home -name lost* >all_result 2>& 1
上面这个例子中将首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 all_result 这个文件中。这样我们就可以将所有的输出都存储到文件中了。为实现上述功能,还有一种简便的写法如下:
$ find /home -name lost* >& all_result
如果那些出错信息并不重要,下面这个命令可以让你避开众多无用出错信息的干扰:
$ find /home -name lost* 2>/dev/null
同学们回去后还可以再试验一下如下几种重定向方式,看看会出什么结果,为什么?
$ find /home -name lost* >all_result 1>& 2
$ find /home -name lost* 2>all_result 1>& 2
$ find /home -name lost* 2>& 1 >all_result
另外一个非常有用的重定向操作符是 ”-“,请看下面这个例子:
$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)
该命令表示把 /source/directory 目录下的所有文件通过压缩和解压,快速的全部移动到 /dest/directory 目录下去,这个命令在 /source/directory 和 /dest/directory 不处在同一个文件系统下时将显示出特别的优势。
条件语句(注意:条件里两边的空格,引号,等号)
if [ ”$var“ = ”abc“ ]; then
…
elif [ ”$var“ = ”ac“ ]; then
…
else
…
fi
for循环
for var in $(ls *.sh); do
echo $var
done
while循环
var=1
while [ ”$var" -le 20 ] ; do
var=$(($var+1))
done
until循环(跟while循环相反的)
until condition
do
…
done
case条件(可用正则,;;相当于break)
case “$var” in
yes | YES | y )
echo “YES”
echo “haha”
;;
[Nn]* ) echo “NO”;;
* ) echo “OTHER”;;
esac
定义/赋值变量
var=xxx (等号两边不能有空格)
变量读取
echo $var
读取用户输入
read var
不输出换行
echo -n
执行命令并捕获返回值
$(command)
其它
shell里默认类型是字符串型
发布在编程算法 已有标签 bash, shell. 将该链接存入书签。 Trackbacks are closed, but you can post a comment.
文档为doc格式