shell编写规则

来源:互联网 发布:单片机的最小系统 编辑:程序博客网 时间:2024/05/22 17:13

第一个shell script程序

#!/bin/bash# Program:#    this is a test shell script# 2015/07/10    zhubinqiang     Fitst releaseecho "Welcome to shell script!"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

脚本第一行 指定/bin/bash解释器执行,虽然以#开头 但不是注释

开头的是单行注释

注释

# 这是单行注释1# 这是单行注释2
  • 1
  • 2
  • 1
  • 2

Shell里面没有多行注释,小技巧实现多行注释

COMMENT_BLOCK=
if [ $COMMENT_BLOCK ]; then===========================echo "comment1"echo "comment2"echo "comment3"===========================fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

变量

a=15version1=$(uname -r)version2=`uname -r`echo $aecho ${version1}echo $version2PATH="$PATH</span>:<span class="hljs-variable">$HOME/bin"export PATHunset a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 变量名=变量, 两边没有空格的。 空格在shell中有特殊用途,分开的话会解释成【命令 参数 参数】的形式
  2. 变量名区分大小写。 name 与 Name 是两个变量
  3. 变量有空格的话要用单引号” 或 双引号 “” 将变量内容结合起来
  4. 上式中</span>a<span>{a} 是相同效果的。使用${a} 避免出错
  5. </span>a<span>{a}。”${a}”是弱引用,输出变量值
  6. export 使变量成为环境变量
  7. unset 取消变量
  8. shell变量是不区分类型的,变量值都是字符串。Bash允许整数比较和运算操作,但变量中只有数字

算术运算

算术运算符

操作符 描述 + 加法运算 - 减法运算 * 乘法运算 / 除法运算 % 求余运算 ** 幂运算 += 加等于 -= 减等于 *= 乘等于 /= 除等于 %= 取模等于

let 运算

a=1let a=a+1echo $a           # 2let a+=1echo $a           # 3 let "a = a + 2"echo $a           # 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

$((…))运算

a=1a=$((a+1))echo $a
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

expr 运算

a=1b=`expr $a + 1`echo $b
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

if … else … 判断语句

a="hello"if [ "$a" == "hello" ]; then    echo "Hello, how are you."elif [ "$a</span>"</span> == <span class="hljs-string">""</span> -o <span class="hljs-string">"<span class="hljs-variable">$a" == '?' ]; then    echo "what?"elif [ "$a</span>"</span> == <span class="hljs-string">'y'</span> ] || [ <span class="hljs-string">"<span class="hljs-variable">$a" == 'Y' ]; then    echo "Yes"else    echo "I don't understand you."fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

[ 左右两边有一个空格, == 左右两边有一个空格,] 左边有一个空格

算术与字符串测试

操作 描述 操作 描述 算术比较 中括号[…]结构 字符串比较 中括号[…]结构 -eq 等于 =/== 等于 -ne 不等于 != 不等于 -lt 小于 \< 小于(ASCII) * -le 小于等于 -gt 大于 \> 大于(ASCII)* -ge 大于等于 -z 字符串为空 -n 字符串不为空 算术比较 双括号((…))结构 条件判断 > 大于 -a 两个条件同时成立 >= 大小于等于 -o 任何一个条件成立 < 大于 ! 非 <= 小于等于

*如果在双中括号[[ … ]]测试中的话,那么不需要转义符\

文件测试

操作 描述 操作 描述 -e 文件是否存在 -s 文件大小不为0 -f 是一个标准文件 -d 是一个目录 -r 文件具有读的权限 -h 文件是一个符号链接 -w 文件具有写的权限 -L 文件是一个符号链接 -x 文件具有执行权限 -b 文件是一个块设备 -c 文件是一个字符设备 -g 设置了sgid标记 -p 文件是一个管道 -u 设置了suid标记 -S 文件是一个socket -k 设置了”粘贴位” -t 文件与一个终端相关联 -N 从这个文件最后一次被读取之后,它被修改过 F1 -nt F2 文件F1比文件F2新 -O 这个文件的宿主是你 F1 -nt F2 文件F1比文件F2旧 -G 文件的组id与你所在的组相同 F1 -nt F2 文件F1和F2都是同一个文件的硬链接 ! “非”(翻转上边的测试结果)

Case

像C语言中的switch… case…

a="hello"case $a in"hello")    echo "Hello, how are you." ;;"")    echo "what?" ;;*)    echo "I don't understand you." ;;esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

while 循环

i=0s=0while [ "$i" -le 100 ];do    s=$((s+i))    i=$((i+1))doneecho "1 + 2 + 3 + ... + 100 = $s"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

until 循环

i=0s=0until [ "$i" -gt 100 ]; do    s=$((s+i))    i=$((i+1))doneecho "1 + 2 + 3 + ... + 100 = $s"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

for 循环

for i in Tom Jack John; do    echo $idonefor i in $(seq 1 5); do    echo $idonefor i in {1..5}; do    echo $idonefor((i=0; i<5; i++)); do    echo $idone
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

数组

array=(5 4 3 2 1)echo ${array[0]}     # 第一个元素len=${#array[*]}     # 数组长度for((i=0; i<$len; i++));do    echo ${array[$i]}donefor i in ${!array[@]}; do    echo ${array[$i]}done
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

函数

函数定义

function function_name {    command...}function function_name() {    command...}function_name() {    command...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

使用函数

function sayHello() {    local name=$1    echo "Hello $name"    return 0}sayHello "Tom"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

return返回的是状态码。 0 表示成功, 非0表示失败。

如果要返回值用echo

function sum(){    local a=$1    local b=$2    local s=$((a+b))    echo $s}s=`sum 2 3`echo $s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

用shift 获取参数

function sum(){    local a=$1    shift    local b=$1    local s=$((a+b))    echo $s}s=`sum 2 3`echo $s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

I/O操作

终端输入,并赋值

read -p "Your name(within 30s):" -t 30 namedecho $named
  • 1
  • 2
  • 1
  • 2

输出多行

cat << EOFcomment1comment2comment3EOF
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

I/O重定向

COMMAND > filename             # 重定向stdout到文件filenameCOMMAND 1> filename            # 重定向stdout到文件filenameCOMMAND >> filename            # 重定向stdout并追加到文件filenameCOMMAND 1>> filename           # 重定向stdout并追加到文件filenameCOMMAND 2> filename            # 重定向stderr到文件filenameCOMMAND 2>> filename           # 重定向stderr并追加到文件filenameCOMMAND &> filename            # 将stdoutstderr都重定向到filenameCOMMAND &>> filename           # 将stdoutstderr都重定向并追加到filenameCOMMAND > filename 2>&1        # 将stdoutstderr都重定向到filenameCOMMAND >> filename 2>&1       # 将stdoutstderr都重定向并追加到filename
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

管道操作

COMMAND1 | COMMAND2 | COMMAND3cat /etc/passwd | grep "root" | awk -F":" '{print $1}' 
  • 1
  • 2
  • 1
  • 2

管道操作是由前面的stdin传递过来的。 stderr不会传过去

特殊Shell变量

变量 含义 $0 脚本名字 $1 位置参数 #1 $9 位置参数 #9 ${10} 位置参数 #10 $# 位置参数的个数 “$*” 所有的位置参数(作为单个字符串) “$@” 位置参数的个数(作为独立的字符串) ${#*} 传递到脚本中的命令行参数的个数 ${#@} 传递到脚本中的命令行参数的个数 $? 返回值 $$ 脚本的进程IP(PID) $- 传递到脚本中的标志(使用set) $_ 之前命令的最后一个参数 $! 运行在后头的最后一个作业的进程ID(PID)

@”

系统环境变量

变量 含义 $IFS 保存了用于分割输入参数的分割字符,默认识空格 $HOME 当前用户的根目录路径 $PATH 可执行文件的搜索路径 $PS1 第一个系统提示符 $PS2 第二个系统提示符 $PWD 当前工作路径 $EDITOR 系统的默认编辑器名称 $BASH 当前Shell的路径字符串 $EUID “有效”用户ID

字符串操作

表达式 描述 ${#string} $string的长度 ${string:position} 在$string中,从position开始提取字串 ${string:position:length} 在$string中,从position开始取长度为length的字串 ${string#substring} 从变量</span>string<span>substring的字串 ${string##substring} 从变量</span>string<span>substring的字串 ${string%substring} 从变量</span>string<span>substring的字串 ${string%%substring} 从变量</span>string<span>substring的字串 ${string/substring/replacement} 使用</span>replacement,<span>substring ${string//substring/replacement} 使用</span>replacement,<span>substring ${string/#substring/replacement} 如果</span>string<span>substring,那么就用</span>replacement<span>substring ${string/%substring/replacement} 如果</span>string<span>substring,那么就用</span>replacement<span>substring expr match “</span>string<span>substring’ 匹配</span>string<span>substring*的长度 expr “</span>string:<span>substring’ 匹配</span>string<span>substring*的长度 expr index “</span>string<span>substring 在</span>sttring<span>substring的第一个字符出现 expr substr </span>string<span>position $length 在</span>string<span>position开始提取长度为$length的字串 expr match “</span>string{<span>substring}\’ 在</span>string<span>substring* expr “</span>string:\(<span>substring)\’ 从</span>string<span>substring* expr match “</span>string.\(<span>substring)\’ 从</span>string<span>substring* expr “</span>string:.\(<span>substring)\’ 从</span>string<span>substring*

* $substring 是一个正则表达式

结构汇总

操作 描述 中括号 if [ Condition ] 测试结构 if [[ Condition ]] 扩展的测试结构 Array[1]=element1 数组初始化 [a-z] 正则表达式的字符范围 大括号 ${variable} 参数替换 ${!variable} 间接变量引用 { command1; command2; … commandN; } 代码块 {string1, string2, string3} 大括号扩展 小括号 ( command1; command2 ) 子shell中执行的命令组 Array=(element1 element2 emement3) 数组初始化 result=$(COMMAND) 在子shell中执行命令,并将结果赋值给变量 >(COMMAND) 进程替换 <(COMMAND) 进程替换 双小括号 (( var = 78 )) 整型运算 var=$(( 20 + 5 )) 整型运算,并将结果赋值给变量 引号 “$variable” “弱”引用 ‘string’ “强”引用 后置引用 result=`COMMAND` 在子shell中运行命令,并将结果赋值给变量

globbing

*: 匹配任意长度的任意字符
a*b 匹配 ab, a123b

?: 匹配任意单字符
a?b 匹配 a1b, a2b

[]: 匹配指定范围内的 任意单字符
[abc], [a-z], [0-9]

[^]: 匹配任意范围外的任意单字符
[^a-z0-9]

字符合集
[[:space:]]: 所有空白字符
[[:punct:]]: 所有标点字符
[[:lower:]]: 小写字母
[[:upper:]]: 大写字母
[[:alpha:]]: 所有字母
[[:digit:]]: 数字
[[:alnum:]]: 字母数字

举例:在/urs/lib/下列出 以l开头,中间有数字,结尾是小写字母
ls /usr/lib/l*[[:digit:]]*[[:lower:]]

echo -e '\033[32mHello\033[0m'

\033[
\033: Ctrl
单个数字:控制字体
3#: 3表示控制其前景色, #是一个数字
4#: 4表示控制其背景色, #是一个数字
组合使用,彼此间使用;分隔
m: 是固定格式
\033[0m: 控制符到此结束



(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(\n).length;varnumbering = $('
    ').addClass('pre-numbering').hide();
    (this).addClass(hasnumbering).parent().append(numbering);
    for (i = 1; i <= lines; i++) {
    numbering.append(('
  • ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

    这里写代码片

    原创粉丝点击