文档章节

Shell 使用

满小茂
 满小茂
发布于 2015/12/18 21:57
字数 4232
阅读 30
收藏 1

Shell  使用


从命令行中读取值

#!/bin/bash

echo "What is your name?"
read PERSON
echo "Hello, $PERSON"

变量


定义变量:

   variableName=”value”

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

首个字符必须为字母(a-z,A-Z)。

中间不能有空格,可以使用下划线(_)。

不能使用标点符号。

不能使用bash里的关键字(可用help命令查看保留关键字)。

使用变量:

  使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:

  your_name="mozhiyan"
  echo $your_name
  echo ${your_name}

重新定义变量

已定义的变量,可以被重新定义

myUrl="http://see.xidian.edu.cn/cpp/linux/"
echo ${myUrl}
myUrl="http://see.xidian.edu.cn/cpp/shell/"
echo ${myUrl}


推荐给所有变量加上花括号,这是个好的编程习惯。

只读变量

  使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

删除变量

使用 unset 命令可以删除变量。语法:

unset variable_name
echo $$


特殊变量列表

变量  含义

$0  当前脚本的文件名

$n  传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。

$#  传递给脚本或函数的参数个数。

$*   传递给脚本或函数的所有参数。

$@  传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。

$?   上个命令的退出状态,或函数的返回值。

$$   当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。


$* 和 $@ 的区别

$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。

但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

退出状态

$? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。


退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。


不过,也有一些命令返回其他值,表示不同类型的错误。

$? 也可以表示函数的返回值,

转义字符


举个例子:

#!/bin/bash
a=10
echo -e "Value of a is $a \n"

运行结果:

Value of a is 10

这里 -e 表示对转义字符进行替换。如果不使用 -e 选项,将会原样输出:

Value of a is 10\n

命令替换

命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。


命令替换的语法:

`command`

注意是反引号,不是单引号,这个键位于 Esc 键下方。


下面的例子中,将命令执行结果保存在变量中:

#!/bin/bash
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"

运行结果:

Date is Thu Jul  2 03:59:57 MST 2009

Logged in user are 1

Uptime is Thu Jul  2 03:59:57 MST 2009

03:59:57 up 20 days, 14:03,  1 user,  load avg: 0.13, 0.07, 0.15


变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值


可以使用的变量替换形式:

形式     说明

${var}       变量本来的值

${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。

${var:=word}   如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。

${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。

若此替换出现在Shell脚本中,那么脚本将停止运行。

${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。


请看下面的例子:

#!/bin/bash

echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"

echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"

unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"

var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"

echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"

运行结果:

Variable is not set

1 - Value of var isVariable is not set

2 - Value of var is Variable is not set

3 - Value of var isThis is default value

4 - Value of var is PrefixPrefix

5 - Value of var is Prefix

运算符

算数运算符

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

#!/bin/bash

val=`expr 2 + 2`

echo "Total value : $val"

两点注意:

•表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。

•完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

#!/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"
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi


运行结果:

a + b : 30

a - b : -10

a * b : 200

b / a : 2

b % a : 0

a is not equal to b



算术运算符列表

运算符 说明 举例

+ 加法 `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。


注意:条件表达式要放在方括号之间,并且要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。


关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

#!/bin/sh

a=10
b=20
if [ $a -eq $b ]
then
   echo "$a -eq $b : a is equal to b"
else
   echo "$a -eq $b: a is not equal to b"
fi

if [ $a -ne $b ]
then
   echo "$a -ne $b: a is not equal to b"
else
   echo "$a -ne $b : a is equal to b"
fi

if [ $a -gt $b ]
then
   echo "$a -gt $b: a is greater than b"
else
   echo "$a -gt $b: a is not greater than b"
fi

if [ $a -lt $b ]
then
   echo "$a -lt $b: a is less than b"
else
   echo "$a -lt $b: a is not less than b"
fi

if [ $a -ge $b ]
then
   echo "$a -ge $b: a is greater or  equal to b"
else
   echo "$a -ge $b: a is not greater or equal to b"
fi

if [ $a -le $b ]
then
   echo "$a -le $b: a is less or  equal to b"
else
   echo "$a -le $b: a is not less or equal to b"
fi

运行结果:

10 -eq 20: a is not equal to b

10 -ne 20: a is not equal to b

10 -gt 20: a is not greater than b

10 -lt 20: a is less than b

10 -ge 20: a is not greater or equal to b

10 -le 20: a is less or  equal to b





关系运算符列表

运算符 说明 举例

-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。


布尔运算符

先来看一个布尔运算符的例子:

#!/bin/sh
a=10
b=20
if [ $a != $b ]
then   
	echo "$a != $b : a is not equal to b"
else   echo "$a != $b: a is equal to b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then   echo "$a -lt 100 -a $b -gt 15 : returns true"
else   echo "$a -lt 100 -a $b -gt 15 : returns false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then   
	echo "$a -lt 100 -o $b -gt 100 : returns true"
else   
	echo "$a -lt 100 -o $b -gt 100 : returns false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then   
	echo "$a -lt 100 -o $b -gt 100 : returns true
else   
	echo "$a -lt 100 -o $b -gt 100 : returns false
fi

运行结果:

10 != 20 : a is not equal to b

10 -lt 100 -a 20 -gt 15 : returns true

10 -lt 100 -o 20 -gt 100 : returns true

10 -lt 5 -o 20 -gt 100 : returns false



布尔运算符列表

运算符 说明 举例

! 非运算,表达式为 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。


字符串运算符

先来看一个例子:

#!/bin/sh

a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a is equal to b"
else
   echo "$a = $b: a is not equal to b"
fi

if [ $a != $b ]
then
   echo "$a != $b : a is not equal to b"
else
   echo "$a != $b: a is equal to b"
fi

if [ -z $a ]
then
   echo "-z $a : string length is zero"
else
   echo "-z $a : string length is not zero"
fi

if [ -n $a ]
then
   echo "-n $a : string length is not zero"
else
   echo "-n $a : string length is zero"
fi

if [ $a ]
then
   echo "$a : string is not empty"
else
   echo "$a : string is empty"
fi

 

运行结果:

abc = efg: a is not equal to b

abc != efg : a is not equal to b

-z abc : string length is not zero

-n abc : string length is not zero

abc : string is not empty


字符串运算符列表

运算符 说明 举例

= 检测两个字符串是否相等,相等返回 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。

文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。


例如,变量 file 表示文件“/var/www/tutorialspoint/unix/test.sh”,它的大小为100字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:

#!/bin/sh
file="/var/www/tutorialspoint/unix/test.sh"
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"
els
        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


运行结果:

File has read access

File has write permission

File has execute permission

File is an ordinary file

This is not a directory

File size is zero

File exists


文件测试运算符列表

操作符 说明 举例

-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。

-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -b $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。


字符串

单引号

str='this is a string'

单引号字符串的限制:

•单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

•单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

双引号

your_name='qinjx'

str="Hello, I know your are \"$your_name\"! \n"

双引号的优点:

•双引号里可以有变量

•双引号里可以出现转义字符


拼接字符串

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`


数组

定义数组

在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:

    array_name=(value1 ... valuen)

例如:

array_name=(value0 value1 value2 value3)

或者

array_name=(value 0value1 value2 value3)


还可以单独定义数组的各个分量:

array_name[0]=value0array_name[1]=value1array_name[2]=value2

可以不使用连续的下标,而且下标的范围没有限制。


读取数组

读取数组元素值的一般格式是:

    ${array_name[index]}

例如:

valuen=${array_name[2]}

举个例子:

#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"

运行脚本,输出:

$./test.sh

First Index: Zara

Second Index: Qadir

使用@ 或 * 可以获取数组中的所有元素,例如:

${array_name[*]}

${array_name[@]}

举个例子:

#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Method: ${NAME[*]}"
echo "Second Method: ${NAME[@]}"

运行脚本,输出:

$./test.sh

First Method: Zara Qadir Mahnaz Ayan Daisy

Second Method: Zara Qadir Mahnaz Ayan Daisy

获取数组的长度

获取数组长度的方法与获取字符串长度的方法相同,例如:

复制纯文本新窗口

# 取得数组元素的个数

length=${#array_name[@]}

# 或者

         length=${#array_name[*]}

# 取得数组单个元素的长度

          lengthn=${#array_name[n]}



if else语句

#!/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


case esac语句


case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum 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

for循环

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

运行结果:

The value is: 1

The value is: 2

The value is: 3

The value is: 4

The value is: 5


顺序输出字符串中的字符:

for str in 'This is a string'
do    
echo $str
done

运行结果:

This is a string


显示主目录下以 .bash 开头的文件:

#!/bin/bash
for FILE in $HOME/.bash*
do   
	echo $FILE
done

运行结果:

/root/.bash_history

/root/.bash_logout

/root/.bash_profile

/root/.bashrc

while循环


例子:

a=0
while (($a<10)) 
do
   a=$(($a+1))
   echo $a
done

while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。

echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while 
read  FILM
do    
    echo "Yeah! great film the $FILM"
done

运行脚本,输出类似下面:

type <CTRL-D> to terminate

enter your most liked film: Sound of Music

Yeah! great film the Sound of Music


Shell函数

#!/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 $* !" # 传递给函数的所有参数
return  value;  #返回值
}

funWithParam 1 2 3 4 5 6 7 8 9 34 73

ret=$?  // 返回函数参数


,还有几个特殊变量用来处理参数,前面已经提到:

特殊变量 说明

$# 传递给函数的参数个数。

$* 显示所有传递给函数的参数。

$@ 与$*相同,但是略有区别,请查看Shell特殊变量。


$? 函数的返回值。

http://c.biancheng.net/cpp/view/7011.html


© 著作权归作者所有

满小茂
粉丝 79
博文 122
码字总数 138345
作品 0
成都
程序员
私信 提问
shell编程基础(二)

Shell是命令解释器,是Unix/Linux系统中用户和内核交互的接口。Shell脚本是shell程序设计语言编写的程序。 一、交互式或登录(注册)shell 交互式注册(交互式登录)shell:输入用户名(/et...

shw23
2016/06/07
66
0
Linux shell 程序设计1——安装及入门

1、什么是shell? shell是linux内核的“壳”,是用户和内核的桥梁。它类似于windows下的命令提示符,将用户输入的命令解释给内核执行,并返回给用户结果。与windows命令提示符不同的是,she...

宅蓝三木
2014/04/24
68
0
Shell编程基础 shell的结构、执行及变量

12月27日任务 20.1 shell脚本介绍 20.2 shell脚本结构和执行 20.3 date命令用法 20.4 shell脚本中的变量 shell脚本介绍 shell是一种脚本语言,是一名运维工程师所必需掌握的最基本的能力。通...

robertt15
2018/12/27
46
0
Oozie分布式任务的工作流——脚本篇

继前一篇大体上翻译了Email的Action配置,本篇继续看一下Shell的相关配置。 Shell Action Shell Action可以执行Shell脚本命令,工作流会等到shell完全执行完毕后退出,再执行下一个节点。为了...

青夜之衫
2017/12/04
0
0
Linux Shell 入门说明

Shell 简介 Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互...

Zhao-Qian
2015/05/19
314
0

没有更多内容

加载失败,请刷新页面

加载更多

让《强化学习(第2版)》架起一座通往强化学习经典知识宝库的桥梁

上交大计算科学与工程系俞凯教授,5分钟口述讲解,带你快速认识了解年度重磅图书《强化学习(第二版)》! 在 AlphaGo战胜李世石之后,AlphaZero以其完全凭借自我学习超越人类在各种棋类游戏...

博文视点Bv
9分钟前
5
0
TLA7-EVM开发板的处理器、NOR FLASH、DDR3

TLA7-EVM开发板是一款由广州创龙基于Xilinx Artix-7系列FPGA自主研发的核心板+底板方式的开发板,可快速评估FPGA性能。核心板尺寸仅70mm*50mm,底板采用沉金无铅工艺的6层板设计,专业的PCB...

Tronlong创龙
18分钟前
3
0
UUID的变种-有序

为了解决UUID无序的问题,NHibernate在其主键生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime)。 /// <summary> //...

Canaan_
19分钟前
3
0
Netty学习(6)——通道间数据传输

1. FileChannel实现通道间的数据传输 在Java NIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel传输到另外一个channel。 transferFrom() FileChannel的transferF...

江左煤郎
22分钟前
3
0
AngularDOM操作

gtandsn
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部