shell编程基础

echo 输出

转义--- \c 不换行 \t 跳格 \n 换行

echo -n 不换行 
注意:linux系统中,必须用 –e 选项才能使转义控制符有效

 

read 读取数据

read var1 var2...

read 

-p 提示信息 -t 等待用户输入的时间 -n接受指定的字符数 -s 隐藏输入的数据

如果输入的值个数多于变量个数,多余的值会赋给最后一个变量。每个值或每个变量之间有空格

cat 显示文件

cat [-n所有输出行编号 -b 空白行不编号] file1 file2

例1:$cat file1 file2 file3
管道命令 | :可以通过管道把一个命令的输出传递给另外一个命令作为输入。
格式:命令 1 | 命令 2
例2: $cat test.txt | grep ‘hello’

tee 输出打印到显示器且保存到文件

tee [-a追加到文件末尾] file

tee file ->输入内容直接修改文件

ps -e | tee file

Shell输入输出 ------ 标准输入、标准输出、标准错误
文件描述符
输入文件 – 标准输入 0
输出文件 – 标准输出 1
错误文件 – 标准错误 2
常用文件重定向命令:(注意没有空格)
command > file 标准输出重定向到一个文件,错误仍然输出到屏幕
command >> file 标准输出重定向追加到文件file
command 1> file 标准输出重定向到file,1是标准输出文件描述符
command 2>> file 标准错误重定向追加到file
command 1>file 2>&1 标准输出和标准错误一起重定向到文件file

          &1指向file
command >> file 2> &1 标准输出和标准错误一起重定向追加到文件file
command < file1 > file2 以file1做为标准输入,file2做为标准输出
command < file 以file做为文件标准输入
注:上面的command 1>file 2>&1 可以修改为command>file 2>>file

cat -n $1 $2 $3 1>catfile.log 2>catfile.err

标准输出到catfile.log错误输出catfile.err

shell变量

  环境变量(/etc/profile )

定义环境变量:
var_name=value

export var_name

查看环境变量的值:
echo $var_name
删除某个系统环境变量:
unset var_name
注:只是从当前用户shell进程中删除,不会从文件/etc/profile删除

  本地变量

查看echo ${var_name} ---建议使用这个方法

  只读变量

readonly  var_name

  位置变量

作用:向shell 脚本传递参数,参数个数可以任意多,但只有前9个被访问到,shift命令可以更改这个限制。参数以数字编号,每个编号前加$,第一个参数$0 是实际的脚本名字,无论脚本是否有参数,此值均有效,$1 ~ $9 是脚本的第一至第九个参数。 例:$vi test.sh

#!/bin/bash
echo “The script name is : $0”  -》脚本名
echo “The first parameter is : $1” 第一个参数
echo “The second parameter is : $2”
echo “The third parameter is : $3”
echo “The fourth parameter is :$4”
echo “The fifth parameter is : $5”
echo “The sixth parameter is : $6”

shift
echo “The sixth parameter is : $10”

保持文件为可执行文件,执行 $./test.sh would you like to do it

一共9个参数,超出需要使用shift

练习:
写一个简单的脚本文件catfile.sh,要求实现功能:用户随意输入3个文件名,这3个文件的内容能够被cat命令连接起来显示,并且所有行都被标号;用户输入的文件可能真实存在,也可能不存在,需要将标准输出和标准错误分别重定向到文件 catfile.log和catfile.err
Cat -n $1 $2 $3 >catfile.log 2> catfile.err

  

特定变量(预定义变量)

特定的shell变量列表:
$# 传递到脚本的参数个数
$* 以一个单字符串的形式显示所有向脚本传递的参数,与位置变量不同,此项参数可以超过9个,返回的是一个整体参数
$$ 脚本运行的当前进程id号
$! 后台运行的最后一个进程的进程id号
$@ 功能与$*相同,但使用时加引号,并在引号中返回每个参数,返回的是每一个独立参数
$? 显示最后命令退出的状态,0表示正确,其他任何值表示错误
例:修改上例中的test脚本,加上以下内容:
echo “The number of arguments passed: $#”
echo “Show all arguments: $*”
echo “Show my process id: $$”
echo “Did my script go with any errors: $?”

变量运算

例1: $x=20 y=30 #同一行对多个变量赋值,用空格分开。
$((w=x+y))	#运算放在双括号里面
$echo $w
50

例2:	$let k=3*8	#用let 进行运算。
$echo $k
$24
如果没用双括号,也没用let,运算的结果会变成字符串。 

(())算式放在双括号里运算

expr   >>dd=$(expr $aa + $bb)----注意空格

let   >> sum

浮点运算

shell里面需要用工具bc来进行浮点运算,bc是linux下的一个计算工具,对应的程序是/usr/bin/bc。可以直接运行bc,然后在后面输入运算式子进行计算,输入式子之前,需要输入scale的值,它表示小数点后面保留几位,如果没有输入,结果会得到整数部分,而没有小数部分。

例1: $x=20 y=30 #同一行对多个变量赋值,用空格分开。
$((w=x+y))	#运算放在双括号里面
$echo $w
50

例2:	$let k=3*8	#用let 进行运算。
$echo $k
$24
如果没用双括号,也没用let,运算的结果会变成字符串。  

文件测试

test condition 或者 [ condition ]
test是关键字,”[””]”与condition之间有空格。

--------------------------------- 文件状态列表 --
-d 目录      -s 文件长度大于0,非空
-f 一般文件    -w 文件可写
-L 符号链接文件  -r 文件可读
-x 文件可执行  -e 文件存在

test -f file     [ -w file ]

echo $?

逻辑操作 -a  -o !

例1:$[ -r myfile1 -a -w myfile2 ]
$echo $?
例2:$[ -w myfile1 -o -x myfile2 ]
$echo $?
逻辑与,或,非可以用双中括号格式,如下:
[[ condition1 && condition2 ]] 逻辑与
[[ condition1 || condition2 ]] 逻辑或

[[ !condition ]] 逻辑非

命令的与、或、非,格式:
命令1 && 命令2 命令逻辑与,命令1先执行,成功时,命令2才执行
命令1 || 命令2 命令逻辑或,命令1先执行,成功时,命令2不再执行

例子:ls && echo yes || echo no    命令成功执行打印yes否则打印no
例4:如果文件a.txt存在,则删除,不存在不做删除。

字符串测试

字符串测试:测试两个字符串的关系,特别是比较用户输入与变量字符串。
格式:test “string”
test string_operator “string”
test “string1” string_operator “string2”
[ string_operator string ]
[ string1 string_operator string2 ]
注:string_operator是操作符,它的取值:
= 等于 != 不等于 -z 空串 -n 非空串

例子:

$string1=“hello”
$string2=“Hello”
$[ “$string1” = “$string2” ]
$echo $?
注:在进行字符串比较时,建议加上引号。

数值测试

格式:”number1” number_operator “number2”
或者 [ “number1” number_operator “number2” ]
注:number_operator是操作符,它的取值:
-eq (equal)数值相等   -gt(grater than) 大于
-ne (unequal)数值不相等   -lt (less than)小于
-le(less equal) 小于等于 -ge (grater equal)大于等于

例1:$num1=130
$[ $num1 –eq 130 ]
$echo $?

整数的关系运算还可以放在双小括号里面进行,这时的运算符与C语言一致,&&表示与运算,||表示或运算,!表示非,==判断是否相等,!=判断是否不等。
例3: $(( 5>6 ))
$echo $?
1 #5>6不成立,退出状态为1

expr语句手工计算

$expr 10 + 10 #注意空格
$expr 300 / 6 / 5
$expr 30 \* 3 #注意:乘号必须用反斜线屏蔽其特定含义

增量计数,expr在循环中用于增量计算,首先,循环初始化为0,然后循环加1,常用的做法:从expr接受输出赋给循环变量。
例:$LOOP=0
$LOOP=`expr $LOOP + 1`

数值测试,可以用expr测试一个数,如果对非整数进行计算,则返回错误。
例:$expr 1.1 + 1 #返回错误
$expr 1 + 1 #返回2

字符串测试,expr也有返回的状态,但与系统最后返回的值刚好相反,expr返回成功为1,其他值为失败。
例:$value=hello
$expr $value = “hello” #注意等号前后都有空格
$1 #expr执行成功的值
$echo $?
$0 #系统命令返回成功的值

 If条件语句

if      [条件1] 
then    命令1
elif    [条件2]
then    命令2
else     命令3
fi

if [条件1]; then
命令1
fi 
例子(输入一个目录名,判断它里面的内容是否为空)
$vi myfile.sh

#!/bin/bash
DIR=$1
if [ “`ls –A $DIR`”= “” ] 
then
echo “$DIR is indeed empty”
else
echo “$DIR is not empty”
fi


./myfile.sh /etc
#``反斜杠表示运行此命令  
例子(要求用户可以随意输入一个账号,打印出该账号,如果账号为空,打印”You did not) enter any info”
account=$1
if [ "$account" = "" ]
then
echo "you did not enter any info"
else 
echo "$account" 
fi

For语句

用法一
for 变量名 in 列表
do
命令1
命令2
done
用法二
for((i=0;i<n;i++))
do
命令
done
用法1例子
#!/bin/bash
for loop1 in {1..10}	#数字列表
do
echo $loop1
done
用法一例子(打印shell脚本的参数,文件名for4.sh)
#!/bin/bash
for params in $*
do
echo “You supplied $params as a command line option”
done
echo $params
修改添加可执行权限:chmod u+x for4.sh
运行:./for4.sh a b c d e f
用法二例子(99乘法表打印)
#!/bin/bash
for((i=1;i<10;i++))
do 
	for((j=1;j<=i;j++))
	do
	#sloution1
	let sum=$i*$j                   
	echo -en "$i*$j=$sum\t"  
	#solution2
	echo -en "$i*$j=$(($i*$j))\t"
	done
echo
done

#echo -e 使转义符生效
#echo -n 不换行,echo命令默认换行

while语句

while 命令
do
命令1
……
done  
使用while循环读取一个文件的内容
#!/bin/bash
while read FILE1
do
echo “the info is: $FILE1”
done < a.file

until语句

until 条件
do
命令1
……
done

case语句

case 变量 in
模式 1)
命令1
……
;;
模式 2)
命令2
……
;;
esac

case 变量后面必须为in,每个模式必须以右括号结束,case后面的变量可以是常数值,找到匹配模式后,执行相关命令直到;;

练习1:输入某个字母,判断是否元音字母。
#!/bin/bash
echo -n please input a letter from a to z: 
read letter
case $letter in
a|e|i|o|u) 
echo “It is a vowel.”
;;
*)
echo “input error.”	;;
esac

break 允许跳出循环或case语句,在多层循环里,break可以跳出本层循环。
continue类似于break, 区别是continue只会跳过当次的循环,不会跳出整层循环。

函数

函数名( )
{
命令1
……	}
或者:
function 函数名( ) { …… }
例:脚本 func1.sh
#!/bin/bash
hello( )
{
echo “Hello, today’s date is `date`”
}
echo “now, going to the function hello”
hello
echo “back from the function”

本地变量

local varname

变量如果在函数内外名称相同则默认为全局,否则加local为本地

函数返回值

格式: return 从函数中返回,用最后状态$?决定返回值。
return 0 无错误返回 return 1 有错误返回

函数使用

1创建函数 例:function.main

2载入文件

格式: source 路径带文件名 或者 . 路径带文件名
$source ./function.main 或 $ . function.main

3. 检查载入的函数
使用set命令查看已经载入到shell的函数
4. 执行函数
键入函数名,如果需要参数,函数名后面带上参数
$findit hello
5. 修改shell函数,需要借助unset 命令先从shell中删除函数,修改后重新载入。
$unset findit
修改后……重新载入
$. ./function.main
练习:
写一个脚本,和用户进行交互,要求用户输入一个目录名称,通过在脚本中调用函数的方法实现:函数能够对这个目录名称进行判断,如果不是目录,也不是文件,则返回1,否则返回0;如果函数返回1,脚本创建该目录。 #!/bin/bash Is_dir(){ if [ -d $1 -o -f $1 ]; then return 0 else return 1 fi } Is_dir $1 ret=$? if [ $ret = 1 ]; then mkdir $1 fi

变量

变量的叠加

  a=123

  -1--a="$a"456

  -2--a=${a}456

  echo a >>a=123456

 set 查看所有的变量

emv查看环境变量

  set -u 如果不存在可以提示楚

unset name删除变量

变量的区别

  自定义变量只能在当前的用户shell中生效

  环境变量是全局变量

pstree 查看进程树

export将自定义变量变为环境变量

ps1 提示符设置

 

\d 显示日期 \H显示主机名 \t 显示时间 \A 显示时间 \u显示当前用户名

\w显示所在目录绝对路径 \W显示当前目录最后一个目录 \$显示提示符

 locale 显示当前语系

LANG

LC_ALL

declare   [+/-] 选项 变量名

-给变量设定类型

+取消变量类型属性

-a将变量声明为数组类型

-i声明为整形

-x声明为环境变量

-r声明为只读变量

-p显示变量的声明类型

例子:declare -i aa=$bb+$ss

posted @ 2016-08-05 00:36  codeforu2  阅读(579)  评论(0编辑  收藏  举报