shell常用命令

shell简介

shell 脚本的优势在于处理偏操作系统底层的业务,例如,linux内容的很多应用都是使用shell脚本开发的,因为有1000多个linux系统命令为他作支撑,特别是linux正则表达式及三剑客grep、awk、sed等命令。

shell的基本格式

command  [选项][参数]

变量

variable=value
variable='value'
variable="value"
  • 赋值号=周围不能有空格
  • 变量由字母、数字、下划线组成
  • 必须以字母或下划线开头
  • 不能使用shell里面的关键字
echo $variable
echo ${variable}
variable="java"
echo  "I am good at ${variable}Script"
echo  'I am good at ${variable}Script'

变量名外面的{} 是可选的,增加为了识别边界,建议都增加
单引号不会解析字符串中的参数,按字符串输入,双引号会解析

  • 将命令的结果赋值给变量
variable=`command`
variable=$(command)  ## 推荐使用该方式
log=$(cat log.txt)
echo "$log"

command 可以只是一个命令,也可以多个命令;分隔。
$()支持嵌套,反引号不行。
$() 仅在 Bash Shell 中有效,而反引号可在多种 Shell 中使用

注意:如果被替换的命令输出内容包括多行(有换行符),或者连续空格需要双引号包围,否则系统默认空白符填充,多个空格压缩成一个。

  • 只读变量
    readonly 命令定义只读变量,只读变量的值不能改变。
readonly myUrl
  • 删除变量
    unset命令删除变量,变量不能被再次使用,不能删除只读变量
unset variable

命令行参数

运行shell脚本文件,可以传递参数,以1第一个参数。
调用函数时也可以传递参数,shell与其他语言不同,定义时不能指定参数,内部可以通过n形式接受的参数在shell中成为位置参数,除此还有*、?、$$几个特殊参数。

#!/bin/bash
#定义函数
function func(){
echo "language:${1}"
echo "URl:$2"
}
func C++ http://www.baidu.com

如果参数超过10个需要增加{}识别边界

变量 说明
$0 当前脚本的文件名
$n (n>0) 传递给脚本或函数的参数,n数字表示第几个采纳数
$# 传递给脚本或函数的参数个数
$* 传递给脚本或函数的所有参数
$@ 传递给脚本或函数的所有参数。当被双引号包括是意义不同
$? 上一个命令的退出状态,或函数的返回值
$$ 当前shell的进程ID
  • 给脚本文件传递参数
    编写test.sh
#!/bin/bash
echo "process ID:$$"
echo "File Name:$0"
echo "First Parameter:$1"
echo "Second Parameter:$2"
echo "All parameters 1:$@"
echo "All parameters 2:$*"
echo "Total :$#"

运行test.sh

./test.sh shell linux

$?是一个特殊变量,用来获取上一个命令的退出状态,就是上一个命令的执行结果,退出状态是一个数字,一般情况下成功返回0,失败返回1。不过也有一些命令返回其它值,标识不同类型的错误。

#!/bin/bash
if ["$1" ==100]
then
    exit 0
else
    exit 1
fi
  • 获取函数的返回值
#!/bin/bash
#得到两个数相加的和
function add(){
return `expr $1+$2`
}

add 23 50
echo $?

严格来说,shell函数的return标识返回状态,而不是返回值,shell没有专门的返回值关键字。

字符串

字符串是一系列字符的组合,用单引号、双引号或不用引号包围。
三种形式的区别
单引号'' :

  • 任何字符都会原样输出,在其中使用便利是无效的。
  • 字符串不能出现单引号,及时转义也不行。
    双引号"":
  • 如果其中包含变量会被解析
  • 字符串中可以出现双引号,需要转义
    不被引号包围:
  • 出现变量也会被解析,和双引号类似
  • 字符串不能出现空格,否则空格右边的字符串会被当做其它变量或命令解析。
    例,
n=74
str1=$n str2="shell \"script\" $n"
str3='C语言 $n'

=号两边不能有空格

  • 获取字符串长度
str3="111"
echo ${#str3}

在shell中不需要任何运算符,将两个字符串并排放在一起就能实现拼接。

name="shell"
url="wwww"
str1=$name$url
echo str1

字符串截取通常两种方式:指定位置,指定字符

  • 指定位置截取

两个参数:起始位置和截取长度

## 从左向右  ${str:start:length} length可以省略标识末尾,start从0开始
url="1234"
echo ${url:2:3}
echo ${url:1}
## 从右向左 ${str:0-start:length} ,从1开始,截取方向都是从左向右
echo ${url: 0-2:3}
  • 指定字符串
    这种截取无法指定字符串长度,智能从指定字符截取到字符串末尾。
#使用#号截取右边字符,*是通配符一种,*char忽略左边字符串直,#第一个,##最后一个开始到遇到char
${str#*char}
${str##*char}
## 使用%截取左边的字符串 ${str%char*},%与#类似
a="111113e33@44@"
echo ${a%@*}
echo ${a%%@*}

汇总:

格式 说明
${str:start:length} 从字符串左边start开始,向右截取length字符
${str:star} 从字符串左边start开始,截取到结尾
${str:0-start:length} 从字符串右边start开始,向右截取length字符
${str:0-star} 从字符串右边start开始,截取到结尾
${str#*char} 从字符串左边第一次出现char开始,截取右边字符
${str##*char} 从字符串左边最后一次出现char开始,截取右边字符
${str%char*} 从字符串右边第一次出现char开始,截取左边字符
${str%%char*} 从字符串右边最后一次出现char开始,截取左边字符

数组

shell 并没有显示数组的大小,理论上可以存放无限量的数据。获取元素使用下标[],下标自然数。遗憾常用bash shell 只支持一维数组。

  • 数组的定义

使用()表示数组元素,数组之间用空格分隔,弱类型,不要求元素类型相同,长度不固定通过赋值扩展

array_name=(ele1 ele2 ele3)

例如

arr=(20 50 "test")
arr[3]=88   #长度变成了4
arr=([3]=77 [2]="test2")  # 长度变成2,只有 2 3 有值
  • 获取数组元素

array_name 数组名,index是下标 0开始
使用@或*可以获取数组所有元素

${array_name[index]}

例如:

#!/bin/bash

nums=(29 100 13 91)
echo ${nums[@]}
nums[10]=66
echo ${nums[4]}
  • 获取数组长度

通过#获取长度

${#array_name[*]}  获取数组元素个数
${#array_name[index]} # 获取某个元素的字符串长度
  • 数组合并

先利用@或* 将数组扩展成列表,然后再合并到一起

  • 删除数组元素
unset array_name[index]  #删除index元素
unset array_name # 删除数组

数学计算

shell不能直接进行算数运算,需要数学计算命令

运算操作符/运算命名了 说明
(()) 用于整数运算,效率很高,推荐使用
let 用于整数运算,和(())类似
$[] 用于整数运算,没有(())灵活
expr 整数运算,可以处理字符串,不推荐
bc linux下的计算器程序,可以处理整数和小数
declare -i 将变量定义成整数,数学运算时就不需要当做字符串了,功能有限,不支持逻辑运算
  • Shell (())的用法

可以多个,逗号分隔,最后一个计算值作为结果

((表达式))
# 获取表达式值,$
$((表达式))

例,

((a=1+2**3-4%3))
b=$((1+2**3-4%3))
  • let 用法
# let '表达式'  或let "表达式"
let 表达式
# 多个表达式,空格分隔
let c=1+3

if语句

本质上,if检测的是命令的退出状态。

  • if基本语法
if condition
then
  statement(s)
fi
# 写到一行 
if condition; then 
   statement(s)
fi
  • if elif else 语句
if condition
then 
statement1
elif condition2
then
 statement2
else
statement3
fi

例,

read age
read iq
if (($age>18 && &iq < 60))
then 
  echo "不及格"
elif (($age==18 && &iq == 60))
then 
  echo "勉强"
else 
   echo "OK"
fi

test

Shell 内建命令,用来检测某一个条件是否成立。通常和if配合使用。
可进行数值、字符串和文件三方面检测。

test expression
[ expression ]
  • 文件类型检测
选项 说明
-b filename 判断文件是否存在,并且是否为块设备文件
-c filename 判断文件是否存在,并且是否为字符设备文件
-d filename 判断文件是否存在,并且是否为目录
-e filename 判断文件是否存在
-f filename 判断文件是否存在,并且为普通文件
-L filename 判断文件是否存在,并且为符号链接文件
-p filename 判断文件是否存在,并且为管道文件
-s filename 判断文件是否存在,并且是否为非空
-S filename 判断文件是否存在,兵器是否为套接字文件
  • 文件权限检测
选项 说明
-r 判断文件是否存在,并拥有读权限
-w 判断文档是否存在,并拥有写权限
-x 判断文件是否存在,并拥有执行权限
-u 判断文件是否存在,并拥有SUID权限
-g 判断文件是否存在,并是否拥有SGID权限
-k 判断文件是否存在,并是否拥有SBIT权限
  • 文件比较
选项 说明
filename1 -nt filename2 判断filename1的修改时间是否比filename2 新
-ot ...旧
-ef 判断文件的inode是否一致,可以理解是否同一个文件。
#!/bin/bash
read filename
read url
if test -w $filename && test -n $url
then
 echo $url > $filename
echo "写入成功"
else
echo "写入失败"
fi
  • 数值比较相关
选项 说明
-eq 是否相等
-ne 不能
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
  • 字符串判断

不支持>= 和 <= 运算符

选项 说明
-z str 是否为空
-n str 是否非空
str1=str2 str1==str2 是否相等
str1!=str2 不相等
str1>str2 是否大于,防止>被误认为重定向运算符
str1 小于
  • 逻辑运算相关
选项 说明
-a
-o
!
if [ -z "$str1" -o -z "$str2" ]
then
 echo "字符串不能为空"
exit 0
fi
  • test中使用便利建议用双引号包围起来

test 和[] 都是命令,本质上对应一个程序或者一个函数,可都看成函数,命令后的选项和参数最终作为实参传递给函数,使用"" 可以避免很多空值导致的奇葩问题

[[ ]]

shell内置关键字,和test命令相似,检测某个条件是否成立。

#注意两侧有空格
[[ expressioin ]]
  • 不需要把变量名用双引号""包围,即便是空值也不会出错
  • 不需要、也不能对> <进行转义
  • 支持逻辑运算符
[[ -z $str1 || -z $str2 ]] 

-支持正则表达式

[[ str =~ regex ]]

case in

当分支条件多,判断条件简单,使用case in 更方便

case expression in
 pattern1)
      statement1
   ;;
pattern2)
       statement2
   ;;
  ...
*)
statementn
esac
  • expression 既可以是一个变量、数字、字符串、数学表达式或命令执行结果,只要能得到expression的值就可以。
  • pattern 可以是一个数字、字符串、甚至一个简单表达式。
    正则表达式:
格式 说明
* 表示任意字符串
[abc] 标识 a、b、c三者任意一个
[m-n] 从m到n的任意字符
| 标识多重选择,类似或,例如abd|cdr 标识abd 或cdr

例,

#!/bin/bash

printf "input a character"
read -n 1 char
case $char in
     [a-zA-Z])
          printf "\nletter\n"
      ;;
     [0-9])
       printf "\nDigit\n"
;;
*)
 printf "\nerror\n"
esac

while

condition 的用户和if else一致,可以使用 test、[] 、 [[]]、(())

while condition
do
   statements
done

例,

#!/bin/bash
sum=0
echo "请输入你要计算的数据,按ctrl+D结束读取"
while read n
do
  ((sum+=n))
done
echo "The sum is :$sum"

until 循环

与while循环恰好相反,当条件不满足执行。

until condition
do
statements
done

for

Shell for 循环有两种使用形式。

  • C 语言风格的for循环
for((exp1;exp2;exp3))
do
statements
done

  • Python 风格的for in循环

value_list 部分可以省略,效果相当$@

for variable in value_list
do
statements
done
  • 对for in 语法中value_list说明
  1. 直接给出具体指,比如 1 2 3 4 5
  2. 给出一个取值范围 {start..end}
    3.使用命令的执行结果

使用反引号或者$()都可以取得命令执行结果
例,

#!/bin/bash
sum=0
for n in $(seq 2 2 100)
do
 ((sum+=n))
done
echo $sum

for filename in $(ls *.sh)
do
echo $filename
done

4.使用Shell通配符

#!/bin/bash
for filename in *.sh
do 
echo $filename
done

5.使用特殊变量

shell中有多个特殊的变量,例如*、?等

#!/bin/bash
functioin func(){
for str in $@
do
echo $str
done
}
func C++ java Python C#

select in 循环详解

select in 循环用来增强交互性,可以显示出带编号的菜单,用编号选择菜单。

select variable in value_list
do 
statements
done

例如,

#!/bin/bash
echo "what is your favourite OS?"
select name in "Linux" "Windows" "Mac OS" "UNIX"
do
echo $name
done
echo "you have selected  $name"

?用来提示用户输入菜单编号;ctrl+D 组合键结束循环。

注意: select 是无线循环,break 或者ctrl+D 退出循环

break 和continue

使用while、until、for、select 循环是,如果想结束循环使用关键字
shell 中break 和continue 可以跳出多层循环

  • break 关键字

n 表示跳出循环的层数,如果省略n,表示跳出当前循环

break n
  • continue 关键字

n 表示循环的层数。

continue n

例,

#!/bin/bash
sum=0
while read n; 
do
 if((n<1 || n>100)); then
continue
fi
((sum+=n))
done
echo "sum=$sum"

shell 函数详解

shell本质是一段可以重复使用的脚本代码。

函数的定义语法格式如下:

function name(){
statements
[return value]
}
  • 简化写法

建议使用标准写法

name(){
statements
[return value]
}

如果写了function关键字,也可以省略函数名后面的小括号:

function name{
statements
[return value]
}
  • 函数调用

和其它编程语言不同的是,shell函数在定义时不能指定参数,但是调用时却可以带参数
也不限制定义和调用顺序

name param1 param2 param3

实例,

#!/bin/bash
function url(){
echo "hello"
}
url

function getsum(){
local sum=0
for n in $@
do
((sum+=n))
done
return $sum
}
getsum 10 20 44
echo $?

你可能感兴趣的:(shell常用命令)