shell基础
sh "文件.sh" , 之后跟文件名,新开子进程执行
sh -c "命令" , 直接把要执行的命令传递给
sh -c 'let c=$PATH;echo "c=$c"'
"-c"选项使shell解释器从一个字符串
中而不是从一个文件中
读取并执行shell命令。当需要临时测试一小段脚本的执行结果时,可以使用这个选项,如下所示:shell中使用source filename.sh ,是直接运行filename.sh的命令,不创建子shell,
而sh则创建子shell,子shell里面 的变量父shell无法使用,对环境变量的修改也不影响父shell。父shell中的局部变量,子shell也无法使用,只有父shell的环境变量, 子shell能够使用。sh 创建了子shell和当前的shell并行执行,子shell中执行,脚本设置的变量不会影响当前shell。一旦子Shell中的执行完毕,此子Shell随即结束,回到父Shell中,不会影响父Shell原本的环境。另外还需要注意的是:子Shell环境拥有与父Shell相同的环境变量、标准输入、输出、错误。
Shell特殊字符
- 双引号 ":用来使Shell无法认出除字符$、`、\之外的任何字符或字符串,也称之为弱引用。
- 单引号 ':用来使Shell无法认出所有的特殊字符,也称之为强引用。
- 反引号 `:优先执行当前命令。
- 反斜杠 \:有两种作用,
一.使其后的字符失去特殊的含义,如有特殊含义的字符$,也称为转义符。
二.如果放在指令前,有取消别名的作用,例如在“\rm/home/yhc/*.log”中,rm指令前加上\,作用是暂时取消别名的功能,将rm指令还原。 - 分号 ;:允许在一行上放多个命令。
- & :将命令放于后台执行,建议带上nohup。
- 括号() :创建成组的命令。 新开shell子进程
- 大括号{}:创建命令块。
- <>& :重定向。
- *? [] !:表示模式匹配。
- $ :变量名的开头。
- # :表示注释(第一行除外)。
- 空格、制表符、换行符:当作空白。
Shell script: 获取第10+个参数
$10被解释成了$1+0。
解决方法很简单,第10个参数加花括号即可:
#!/bin/bash
echo $1 $2 $3 $4 $6 $7 $8 $9 ${10}
元字符
具有特定功能的保留字 主要内容: 如果表达式中包含特殊字符,Shell 将会进行替换,转义字符也是一种替换。 可以使用 echo 命令的 -E 选项禁止转义, -e 选项是转义; Bash 支持很多运算符,包括 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。 先来看一个使用算术运算符的例子: 运行结果: 文件测试运算符用于检测 Unix 文件的各种属性。 例子: 字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。 单引号和双引号的区别 : [ "$str" = "" ] 待找个更好的 #(五) 数组 在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为: 例如: 读取数组元素值的一般格式是: 例如: 使用 获取数组长度的方法与获取字符串长度的方法相同, 例如: 主要内容 Shell 有三种 if ... else 语句: 注意:expression 和方括号([ ])之间必须有空格,否则会有语法错误。 例如: 例如: 哪一个 expression 的值为 true,就执行哪个 expression 后面的语句;如果都为 false,那么不执行任何语句。 例如: if ... else 语句也经常与 test 命令结合使用, test 命令用于检查某个条件是否成立,与方括号([ ])类似。 取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。 例如: 条件测试使用 使用方法: 语法: ((表达式1,表达式2…)) 特点: 1、在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。 a=a+1 2、在双括号结构中,所有变量可以不加入:“$”符号前缀。 3、双括号可以进行逻辑运算,四则运算 4、双括号结构 扩展了for,while,if条件测试运算 5、支持多个表达式运算,各个表达式之间用逗号“,”分开 主要内容 for循环一般格式为: 列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。 例一 例二 例三 while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件,条件为真时继续循环。其格式为: 例一 例二 until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。 例 在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell也使用 break 和 continue 来跳出循环。 break命令允许跳出本层所有循环(终止执行后面的所有循环) 例如: 如上,break 2 表示直接跳出外层循环。 continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 主要内容 函数可以将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。函数必须先定义后使用。 定义格式如下: 或 例: 删除函数也可以使用 unset 命令,不过要加上 .f 选项,如下所示: 调用只需要给出函数名,不需要加括号。 调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数... 例如: 输出: 另外: shift: 参数左移指令, 每执行一次,参数序列顺次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数,不再可用。 例: 文件包含即将外部脚本的内容合并到当前脚本。 可以使用: 或 两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。 例如: 一个是主文件 main.sh,内容如下: 注意:被包含脚本不需要有执行权限。 由于编码问题,在windows中开发的脚本导入到Linux系统后执行报错,主要是因为在windows开发保存时没注意编码(UTF8)和换行符(LF)。 安装 使用 主要内容 shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e开启转义 例: 注: 可以自己来尝试找出不同颜色搭配 最后面控制选项说明 \33[0m 关闭所有属性IFS(交换字段分隔符)
:由CR(回车键)
: 由=
: 设定变量。$
: 做变量或运算替换(请不要与 shell prompt 搞混了)。>
: 重定向 stdout(标准输出standard out)。<
: 重定向 stdin(标准输入standard in)。|
: 管道命令。&
: 重定向 file descriptor (文件描述符),或将命令置于后台执行。( )
: 將其內的命令置于 nested subshell (嵌套的子shell)执行,或用于运算或命令替换。{ }
: 將其內的命令置于 non-named function(未命名函数) 中执行,或用在变量替换的界定范围。;
: 在前一个命令结束时,而忽略其返回值,继续执行下一個命令。&&
: 在前一個命令结束时,若返回值为 true,继续执行下一個命令。||
: 在前一個命令结束时,若返回值为 false,继续执行下一個命令。!
: 执行 history 列表中的命令;
: 分隔同一行的2条shell语句。转义符
下面的转义字符都可以用在 echo 中:转义字符 含义 \ 反斜杠 \a 警报,响铃 \b 退格(删除键) \f 换页(FF),将当前位置移到下页开头 \n 换行 \r 回车 \t 水平制表符(tab键) \v 垂直制表符 ╭─sam@sam ~
╰─$ echo -E "Value of a is \n nnnnnnnnnnn "
Value of a is \n nnnnnnnnnnn
╭─sam@sam ~
╰─$ echo "Value of a is \n nnnnnnnnnnn "
Value of a is
nnnnnnnnnnn
╭─sam@sam ~
╰─$ echo -e "Value of a is \n nnnnnnnnnnn "
Value of a is
nnnnnnnnnnn
默认是不转义的
;
在没有 -E 的情况下,可承认并可以内置替换以下序列: \NNN 字符的ASCII代码为NNN(八进制)
\\ 反斜线
\a 报警符(BEL)
\b 退格符
\c 禁止尾随的换行符
\f 换页符
\n 换行符
\r 回车符
\t 水平制表符
\v 纵向制表符
(三) 运算符
主要内容
算数运算符
#!/bin/sh
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
注意
:算术运算符列表
运算符 说明 举例 + 加法 expr $a + $b
结果为 30。- 减法 expr $a - $b
结果为 10。* 乘法 expr $a \* $b
结果为 200。/ 除法 expr $b / $a
结果为 2。% 取余 expr $b % $a
结果为 0。= 赋值 a=$b 将把变量 b 的值赋给 a。 == 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。 != 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。 关系运算符
运算符 说明 举例 -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。 -ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。 -ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。 -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。 布尔运算符
运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。 -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 字符串运算符
运算符 说明 举例 = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。 -n 检测字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。 str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。 文件测试运算符
操作符 说明 举例 -b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。 -c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。 -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。 -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。 -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。 -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。 -p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。 -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。 -r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。 -w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。 -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。 -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。 -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。 if [ -r $file ]
then
echo "File has read access"
else
echo "File does not have read access"
fi
if [ -w $file ]
then
echo "File has write permission"
else
echo "File does not have write permission"
fi
if [ -x $file ]
then
echo "File has execute permission"
else
echo "File does not have execute permission"
fi
if [ -f $file ]
then
echo "File is an ordinary file"
else
echo "This is sepcial file"
fi
if [ -d $file ]
then
echo "File is a directory"
else
echo "This is not a directory"
fi
if [ -s $file ]
then
echo "File size is zero"
else
echo "File size is not zero"
fi
if [ -e $file ]
then
echo "File exists"
else
echo "File does not exist"
fi
(四) 字符串
主要内容
字符串拼接
name="sam"
greeting="hello, "$name" !"
greeting_1="hello, ${name} !"
字符串长度
string="abcd"
echo ${#string} # 4
字符串截取
string="Hello world, shell"
echo ${string:0:4} #输出Hell
echo ${string:1:4} #输出ello
echo ${string:1:1} #输出e
字符串长度
$(awk 'BEGIN {print length("'$str'")}')
$(expr length $str)
$(echo "$str" | wc -c) # 结果多1
判断字符串为空
[ -z "$str" ]字符串截取
str="^ababa$"
echo ${str#*b} # aba$
echo ${str##*b} # a$
echo ${str%b*} # ^aba
echo ${str%%b*} # ^a
1、第一种方法:
${varible##*string} 从左->右截取最后一个string后的字符串
${varible#*string}从左->右截取第一个string后的字符串
${varible%%string*}从右<-左截取最后一个string后的字符串
${varible%string*}从右<-左截取第一个string后的字符串
“*”只是一个通配符可以不要
# % 右向左移除 非贪婪匹配
# %% 右向左移除 贪婪匹配
# # 左向右移除 非贪婪匹配
# ## 左向右移除 贪婪匹配
URL="www.txazo.com"
echo ${URL%.*} # www.txazo
echo ${URL%%.*} # www
echo ${URL#*.} # txazo.com
echo ${URL##*.} # com
${string:index:length}
, index 从 0 开始。字符串查找
string="alibaba is a great company"
echo `expr index "$string" is` #3 , i或s最早出现的地方
主要内容
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。数组定义
array_name=(value1 ... valuen)
array_name=(value0 value1 value2 value3)
#或者
array_name=(
value0
value1
value2
value3
)
#或者
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
#可以不使用连续的下标,而且下标的范围没有限制。
数组读取
${array_name[index]}
valuen=${array_name[2]}
@ 或 *
可以获取数组中的所有元素,例如:${array_name[*]}
${array_name[@]}
数组长度
#
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
(六) 条件判断
*if ... else 语句
if ... fi 语句;
if ... else ... fi 语句;
if ... elif ... else ... fi 语句。
if ... fi
if ... fi
语句的语法:if [ expression ]
then
Statement(s) to be executed if expression is true
fi
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi
if ... else ... fi 语句
if ... else ... fi
语句的语法:if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi
if ... elif ... fi 语句
if ... elif ... fi
语句可以对多个条件进行判断,语法为:if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi
test
if test $[a] -eq $[b]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi
case ... esac 语句
case ... esac
是一种多分枝选择结构。case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。
case语句格式如下:case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
* )
command1
command2
command3
;;
esac
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
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'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac
option="${1}"
case ${option} in
-f) FILE="${2}"
echo "File name is $FILE"
;;
-d) DIR="${2}"
echo "Dir name is $DIR"
;;
*)
echo "`basename ${0}`:usage: [-f file] | [-d directory]"
exit 1 # Command to come out of the program with status 1
;;
esac
扩展 (())
[]
时候,必须保证运算符与算数之间有空格。四则运算也只能借助:expr命令完成。 双括号 (())
结构语句,可以扩展shell中算数及赋值运算。(七) 循环
for循环
for 变量 in 列表
do
command1
command2
...
commandN
done
in
列表是可选的,如果不用它,for 循环使用命令行的位置参数。
顺序输出当前列表中的数字:for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
顺序输出字符串中的字符:for str in 'This is a string'
do
echo $str
done
显示主目录下以 .bash 开头的文件:#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
while循环
while command
do
Statement(s) to be executed if command is true
done
COUNTER计数COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done
读取键盘信息,按echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo "Yeah! great film the $FILM"
done
until循环
command 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
until 循环格式为:until command
do
Statement(s) to be executed until command is true
done
输出 0 ~ 9a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
跳出循环
break
break n
表示跳出第 n 层循环。 for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
continue
continue n
表示跳出第 n 层循环。(八) 函数, 文件包含, 转码工具
函数
函数定义
function function_name () {
list of commands
[ return value ]
}
function_name () {
list of commands
[ return value ]
}
function
可以省略,清晰起见,还是建议加上。函数返回值
#!/bin/bash
funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"
函数删除
$unset .f function_name
函数调用
# Define your function here
Hello () {
echo "Url is http://giveme5.top"
}
# Invoke your function
Hello
函数参数
注意,当n>=10时,需要使用 ${n}
来获取参数。 获取第十个参数需要 ${10}
, $10 不能获取第十个参数。#!/bin/bash
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !" # 参数个数
echo "The string of the parameters is $* !" # 传递给函数的所有参数
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
he value of the first parameter is 1 !
The value of the second parameter is 2 !
The value of the tenth parameter is 10 !
The value of the tenth parameter is 34 !
The value of the eleventh parameter is 73 !
The amount of the parameters is 12 !
The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
几个特殊变量用来处理参数(更多特殊变量):特殊变量 说明 $# 传递给函数的参数个数。 $* 显示所有传递给函数的参数。 $@ 与$*相同,但是略有区别,请查看更多特殊变量。 $? 函数的返回值。 shift
加法计算器,通过 shift
指令使参数左移,求出所有参数的和#!/bin/bash
if [ $# -le 0 ]
then
echo "err!:Not enough parameters"
exit 124
fi
sum=0
while [ $# -gt 0 ]
do
sum=`expr $sum + $1`
shift #参数左移
done
echo $sum
文件包含
. filename
source filename
创建两个脚本,一个是被调用脚本 subscript.sh,内容如下: url="http://see.xidian.edu.cn/cpp/view/2738.html"
#!/bin/bash
. ./subscript.sh
echo $url
dos2unix
在Linux中可以用工具dos2unix解决。
[root@localhost test]#rpm -ivh /mnt/Packages/dos2unix-6.0.3-4.el7.x86_64.rpm
[root@localhost ]# dos2unix test.sh
dos2unix: converting file test.sh to Unix format ...(九) 色彩
色彩
echo -e "\033[字背景颜色;文字颜色 m字符串\033[0m"
\033[
是固定语法; 0m
是清除所有格式
其中42的位置代表底色,31的位置代表的是字的颜色1、字背景颜色和文字颜色之间是英文的";"
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m — \33[37m 设置前景色
\33[40m — \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标