shell编程笔记(基本部分)
1.变量
a.需要给变量赋值时,可以这么写:
b.要取用一个变量的值,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在"="两边留空格 )
c.然后执行 chmod +x first 使其可执行,最后输入 ./文件名 执行该脚本。
#!/bin/bash
# 对变量赋值:
a="hello world" #等号两边均不能有空格存在
# 打印变量a的值:
echo "A is:" $a
如果变量与字符串混合,则按此方法
num=2
echo "this is the ${num}nd"
需要注意shell的默认赋值是字符串赋值
var=1
var=$var+1
echo $var #结果为1+1,不是2
推荐采用以下方法
let "var+=1" #方法1
var="$[$var+1]" #方法2
((var++)) #方法3
var=$(($var+1)) #方法4 注:前2种方式在bash下有效,在sh下会出错。
2.if 语 句
if ....; then
....
elif ....; then
....
else
....
fi
大多数情况下,可以使用测试命令来对条件进行测试,比如可以比较字符串、判断文件是否存在及是否可读等等……通常用" [ ] "来表示条件测试,注意这里的空格很重要,
要确保方括号前后的空格。
- [ -f "somefile" ] :判断是否是一个文件
- [ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
- [ -n "$var" ] :判断$var变量是否有值
- [ "$a" = "$b" ] :判断$a和$b是否相等
- 例如:
#!/bin/bash if [ ${SHELL} = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but ${SHELL}"
fi
变量$SHELL包含有登录shell的名称,我们拿它和/bin/bash进行比较以判断当前使用的shell是否为bash。
3.&& 和 || 操作符
#!/bin/bash mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ] || { echo "Can not read $mailfolder" ; exit 1; }
echo "$mailfolder has mail from:"
grep "^From " $mailfolder
该脚本首先判断mailfolder是否可读,如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。需要注意的是,这里我们必须使用如下两个命令:
- -打印错误信息
- -退出程序
我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用;普通函数稍后再作说明。即使不用与和或操作符,我们也可以用if表达式完成任何事情,但是使用与或操作符会更便利很多 。
4.case 语句
case ... in
...) do something here
;;
esac
例如:制作一个smartzip脚本,该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件
#!/bin/bash ftype="$(file "$1")"
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*) echo "File $1 can not be uncompressed with smartzip";;
esac
你可能注意到上面使用了一个特殊变量$1,该变量包含有传递给该脚本的第一个参数值。也就是说,当我们运行:
smartzip articles.zip
$1 就是字符串 articles.zip。
5.select 语句
select var in ... ; do
break;
done
.... now $var can be used ....
例如:
#!/bin/bash echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break;
done
echo "You have selected $var"
该脚本的运行结果如下:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux
6.while/for 循环
while ...; do
....
done
只要测试表达式条件为真,则while循环将一直运行。关键字"break"用来跳出循环,而关键字”continue”则可以跳过一个循环的余下部分,直接跳到下一次循环中。
for循环会查看一个字符串列表(字符串用空格分隔),并将其赋给一个变量:
for var in ....; do
....
done
下面的示例会把A B C分别打印到屏幕上:
#!/bin/bash for var in A B C ; do
echo "var is $var"
done
下面是一个实用的脚本showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/bash # list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in "$@"; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
这里出现了第二个特殊变量$@,该变量包含有输入的所有命令行参数值。如果你运行showrpm openssh.rpm w3m.rpm webgrep.rpm,那么 "$@"(有引号) 就包含有 3 个字符串,即openssh.rpm, w3m.rpm和 webgrep.rpm。$*的意思是差不多的。但是只有一个字串。如果不加引号,带空格的参数会被截断。
7.Shell里的一些特殊符号
在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓的扩展是指程序会把通配符(比如*)替换成适当的文件名,把变量替换成变量值。我们可以使用引号来防止这种扩展,先来看一个例子,假设在当前目录下有两个jpg文件:mail.jpg和tux.jpg。
- 单引号字串中不能出现单引号(对单引号使用转义符后也不行)
#!/bin/bash echo *.jpg
运行结果为:
mail.jpg tux.jpg
引号(单引号和双引号)可以防止通配符*的扩展:
#!/bin/bash echo "*.jpg"
echo '*.jpg'
其运行结果为:
*.jpg
*.jpg
其中单引号更严格一些,它可以防止任何变量扩展;而双引号可以防止通配符扩展但允许变量扩展:
#!/bin/bash echo $SHELL
echo "$SHELL"
echo '$SHELL'
运行结果为:
/bin/bash
/bin/bash
$SHELL
此外还有一种防止这种扩展的方法,即使用转义字符——反斜杆:\:
echo \*.jpg
echo \$SHELL
输出结果为:
*.jpg
$SHELL
8.Here Document
当要将几行文字传递给一个命令时,用here document是一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果使用here document就不必用echo函数一行行输出。Here document以 << 开头,后面接上一个字符串,这个字符串还必须出现在here document的末尾。下面是一个例子,在该例子中,我们对多个文件进行重命名,并且使用here document打印帮助:
#!/bin/bash # we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat << HELP ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp' 'replacement' files... EXAMPLE: rename all *.HTM files in *.html:
ren 'HTM$' 'html' *.HTM HELP #这里HELP要顶格写,前面不能有空格或者TAB制表符。如果cat一行写成cat << -HELP,前边可以带TAB.
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $@ contains now all the files:
for file in "$@"; do
if [ -f "$file" ] ; then
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; then
echo "ERROR: $newfile exists already"
else
echo "renaming $file to $newfile ..."
mv "$file" "$newfile"
fi
fi
done
第一个if表达式判断输入命令行参数是否小于3个 (特殊变量$# 表示包含参数的个数) 。如果输入参数小于3个,则将帮助文字传递给cat命令,然后由cat命令将其打印在屏幕上。打印帮助文字后程序退出。如果输入参数等于或大于3个,我们就将第一个参数赋值给变量OLD,第二个参数赋值给变量NEW。下一步,我们使用shift命令将第一个和第二个参数从参数列表中删除,这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量$file。接着我们判断该文件是否存在,如果存在则通过sed命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给newfile。这样我们就达到了目的:得到了旧文件名和新文件名。然后使用 mv命令进行重命名。
9.Shell里的函数
functionname()
{
# inside the body $1 is the first argument given to the function
# $2 the second ...
body
}
下面是一个名为xtitlebar的脚本,它可以改变终端窗口的名称。这里使用了一个名为help的函数,该函数在脚本中使用了两次:
#!/bin/bash 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 这个变量是不是空字符串 如果是,则返回真
[ "$1" = "-h" ] && help
# send the escape sequence to change the xterm titelbar:
echo -e "\033]0;$1\007"
#
在脚本中提供帮助是一种很好的编程习惯,可以方便其他用户(和自己)使用和理解脚本。
字符串操作
拼接字符串
your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
获取字符串长度:
string="abcd"
echo ${#string} #输出:4
提取子字符串
string="alibaba is a great company"
echo ${string:1:4} #输出:liba
查找子字符串
string="alibaba is a great company"
echo `expr index "$string" is`#输出:8,这个语句的意思是:找出单词is在这名话中的位置
可以使用source和.关键字,如:
source ./function.sh
. ./function.sh
在bash里,source和.是等效的,他们都是读入function.sh的内容并执行其内容(类似PHP里的include),为了更好的可移植性,推荐使用第二种写法。
包含一个文件和在执行一个文件一样,也要写这个文件的路径,不能光写文件名,比如上述例子中:
. ./function.sh
不可以写作:
. function.sh
如果function.sh是用户传入的参数,如何获得它的绝对路径呢?方法是:
real_path=`readlink -f $1`#$1是用户输入的参数,如function.sh
. $real_path
shell编程笔记(基本部分)的更多相关文章
- Shell编程笔记
Shell编程笔记与Windows下熟悉的批处理类似,也可以将一些重复性的命令操作写成一个脚本方便处理. 修改别人的脚本,运行后遇到个问题 setenv: command not found 查证 ...
- shell编程笔记(1)
shell编程: 编译器,解释器 编程语言:机器语言.汇编语言.高级语言 静态语言:编译型语言 强类型(变量) 事先转换成可执行格式 C.C++.JAVA.C# ...
- linux系列之-—01 shell编程笔记
一.特殊变量($0.$1.$2. $?. $# .$@. $*) shell编程中有一些特殊的变量可以使用.这些变量在脚本中可以作为全局变量来使用. 名称 说明 $0 脚本名称 $1-9 脚本执行时的 ...
- SHELL编程笔记(二)之shell流程控制
Shell控制流程结构 本章内容有: 退出状态 While.for和until loops循环 If then else语句 脚本中动作 菜单 条件控制语句 If then els ...
- shell 编程笔记
#! /bin/sh 寻找shell解释器 /bin/sh 是一个路径 #! /usr/bin/python 仅仅是寻找一个python的解释器 执行linux程序的方法: 使得文件具有可执行的权限 ...
- 小苏的Shell编程笔记之六--Shell中的函数
http://xiaosu.blog.51cto.com/2914416/531247 Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以 ...
- shell编程笔记1
参考文章:1 http://blog.csdn.net/wuwenxiang91322/article/details/9259877 通过chmod改变文件权限 补充知识: 1Linux文件的三 ...
- ubuntu shell编程笔记
and 命令 if [ A -a B ] then else fi while [ ] do done set command set these are parameters $1 s ...
- linux shell 编程笔记
重定向和管道 输出重定向:把在终端输出的内容保存到文件上 输入重定向:通过文件的格式输入内容到终端 管道:把上一条命令的输出作为下一条命令的输入,如同管道一样,所有命令同时进行,同时处理数据,不 ...
随机推荐
- Java反射机制简单使用
1.Java反射相关类所在package: java.lang.reflect.* 2.开始使用Reflection: 使用reflect相关类,遵循三个步骤: a.获取想要操作类的 java.lan ...
- mysql导入.sql文件
1. source /home/susie ...../**.sql 2. \. /home/susie/.../**.sql 批量导入.sql文件 首先新建一个main.sql,然后在main.sq ...
- Python中for\while的用法
代码示例 board = [] for i in range(5): board.append(i) print board board = [] i = 0 while i < 5: boar ...
- 常见的SQL字符串函数
1.LEN:计算字符串的长度(字符的个数) select len('哈哈hello') 返回长度为7 2.datalength();计算字符串所占用的字节数,不属于字符串函数 select DATAL ...
- 使用Spring Boot和Gradle创建AngularJS项目
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的 ...
- NASM mode for Emacs
NASM mode for Emacs Quick post for those Emacs users out there. The common assembler used on GNU ...
- USB设备类型代码(class类型)
Base Class E0h (Wireless Controller) This base class is defined for devices that are Wireless contro ...
- jQuery插件之Form
一.jQuery.Form.js 插件的作用是实现Ajax提交表单. 方法: 1.formSerilize() 用于序列化表单中的数据,并将其自动整理成适合AJAX异步请求的URL地址格式. 2.cl ...
- 多个ORACLE HOME的情况,默认的ORACLE HOME是哪个,以及如何更改HOME
如果系统里安装了多个ORACLE产品,那么在注册表里,有可能也会有多个ORACLE HOME,在不设置系统环境变量的情况下,默认情况使用哪个ORACLE HOME? HKEY_LOCAL_MACHIN ...
- 【转】【经典算法】——KMP,深入讲解next数组的求解
前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k:但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导 ...