bash shell脚本常用功能

来源:互联网 发布:数据透视表不显示总计 编辑:程序博客网 时间:2024/05/03 04:54

转自:http://blog.sina.com.cn/s/blog_803458bd0101egd3.html

目录:

第一章 简介
  $ 表示普通用户
  #!/bin/bash
  ~/.bashrc
  ~/.bash_history
第二章 终端打印
  1,echo输出
  2, printf输出
第三章 变量和环境变量
  env命令 查看当前终端的环境变量
  pgrep debug.sh  查看某一应用的进程ID
  cat /proc/PID/environ  查看该进程的环境变量
  cat /proc/26574/environ | tr '\0' '\n'
  export命令用来设置环境变量,
  环境变量PATH

  还有一些环境变量 HOME PWD USER UID  SHELL

  1.3.3 有关普通变量和环境变量的补充内容 
  1 获取字符串长度  ${#var}
  2 识别当前的shell版本  echo $SHELL  也可以用 echo $0
  3 检查是否为超级用户 
    超级用户的UID是0   if [ $UID -ne 0 ]; then ... else ... fi
  4 修改bash提示字符串(username@hostname:~$

第四章 通过shell进行数学运算
  bash shell环境中,可以利用let, (())和[]执行基本的算术操作符。
  expr和bc可以用于高级算术操作。


第五章 玩转文件描述符和重定向
  文件描述符是与文件输入,输出相关联的整数,他们用来跟踪已打开的文件,最常见的文件描述符是stdin, stdout, stderr。 我们可以将某个文件描述符的内容重定向到另一个文件描述符中。
  命令执行成功与否的情况
  cmd 2>stderr.txt 1>stdout.txt
  cmd 2>&1 output.txt
  cmd &> output.txt


tee命令 一方面将数据重定向到文件,另一方面还可以提供一份重定向数据副本作为后续命令的stdin

1,将文件重定向到命令     cmd < file
2,重定向脚本内部的文本块  cat <<EOF>log.txt与下一个EOF
3,自定义文件描述符   exec命令创建自定义的文件描述符
   ** 分配文件描述符3 给input.txt 用于从文件中读取信息。
   ** 创建文件描述符用于写入到文件中(截断模式)
   ** 创建文件描述符用于追加写入 (追加模式)

第六章 数组和关联数组
  普通数组:只能用整数作为数组索引
  关联数组:可以使用字符串作为数组索引

第七章 使用别名
  第一种方式 alias  alias rm='cp $@ ~/backup; rm $@'
  第二种方式 函数 

第八章 获取终端信息
  tput
  stty

第九章 获取,设置日期和延时
  timescriptpath

第十章 调试脚本
  bash -x script.sh  启动跟踪调试shell脚本
  [ "$_DEBUG" == "on" ] && $@ || : 
   举例说:
   脚本名称叫test.sh 入参三个: 1 2 3  
   运行test.sh 1 2 3后   
   $* 为"1 2 3"(一起被引号包住)  
   $@ 为"1" "2" "3"(分别被包住)
   $# 为3(参数数量)


第十一章 函数和参数

第十二章 读取命令序列输出

第十三章 以不按回车键的方式读取字符 "n"
  read -n 2 var    
  read -p "enter:" var 
  read -s var   
  read -t 5 var
  read -d ":" var

第十四章  字段你分隔符和迭代器
  内部字段分隔符(internal field separator IFS)

第十五章 比较与测试
  算术比较 -o 逻辑或  -a 逻辑与
  逻辑判断 || 逻辑或  && 逻辑与

  if和else语句条件判断部分会很长,可以用逻辑运算符使他变得简洁
 
 算术比较
  多个条件进行测试
  文件系统相关测试
  使用test命令,可以避免括号过多


第一章 简介
$ 表示普通用户
# 表示超级用户

#!/bin/bash
#! 称作 shebang 在unix里面,用sharp或者hash称#   用bang称!
/bin/bash 是Bash的路径

当打开一个终端时,该终端最初会执行一组命令来定义诸如提示文本,颜色等各种设置。这组命令来自位于用户home目录的.bashrc脚本文件中(~/.bashrc)
bash还维护了一个历史记录文件~/.bash_history 用于保存运行过得命令
~ 是一种简写,代表用户home目录的路径。

第二章 终端打印
1,echo输出
参数 -n 忽略换行
     -e 转义
如果输出没有特殊字符的字符串,三种方式都没有问题
echo hello world
echo 'hello world'
echo "hello world"

如果有特殊字符的输出,使用单引号,单引号会把引号里面的任何字符转义成普通字符,再输出。即单引号里面的任何字符的特殊含义都会被屏蔽
echo 'hello world !'

echo的彩色文本输出
重置:0   黑色:30   红色:31   绿色:32   黄色:33   蓝色:34   洋红:35   青色:36   白色:37
y$ echo -e "\e[1;31m this is red text \e[0m"
 this is red text
\e[0m 作用是把后面的颜色重置为原来颜色
echo设置彩色背景输出
重置:0   黑色:40   红色:41   绿色:42   黄色:43   蓝色:44   洋红:45   青色:46   白色:47
y$ echo -e "\e[1;41m this is red text \e[0m"
 this is red text

2, printf输出
printf可以指定字符串的宽度,左右对齐方式。默认printf不会自动换行,需要添加\n
%s %c %d %f是格式替代符(format substitution character)
%-5s 指定一个格式为左对齐宽度为5的字符串替代,左对齐,如果字符串不够则用空格替代。
#!/bin/bash
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 Sarath 80.3456
printf "%-5s %-10s %-4.2f\n" 2 James 90.9989
printf "%-5s %-10s %-4.2f\n" 3 Jeff 77.564
输出:
No    Name       Mark
    Sarath     80.35
    James      91.00
    Jeff       77.56

第三章 变量和环境变量
env 命令查看与此终端进程相关的环境变量
对于每个进程,其运行时的环境变量用如下查看 cat /proc/$PID/environ
例如,debug.sh脚本在运行,可以通过下面的方式获取该进程的ID
pgrep debug.sh
列出的环境变量都是以name=value的形式表示,彼此用null字符(\0)分割
这里用换行替换\0 
cat /proc/26574/environ | tr '\0' '\n'

1.3.2 实战演练
var=value  是赋值操作
var = value 是相等操作

环境变量是从父进程继承而来的变量。例如 HTTP_PROXY
HTTP_PROXY=http://192.168.0.2:3128
export HTTP_PROXY
export命令用来设置环境变量,

环境变量PATH
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

给PATH添加新路径,有如下方法1
$ export PATH="$PATH:/home/user/bin"
~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/user/bin

方法2
PATH="$PATH:/home/user/bin"
export PATH


还有一些环境变量 HOME PWD USER UID  SHELL


1.3.3 有关普通变量和环境变量的补充内容 
1 获取字符串长度  ${#var}
2 识别当前的shell版本  echo $SHELL  也可以用 echo $0
3 检查是否为超级用户  超级用户的UID是0   if [ $UID -ne 0 ]; then ... else ... fi
4 修改bash提示字符串(username@hostname:~$
  利用PS1环境变量订制提示文本,默认的shell提示文本在文件~/.bashrc中的某行设置
列出PS1
cocktail@COCKTAILL7:~$ cat ~/.bashrc | grep PS1
[ -z "$PS1" ] && return
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"

* 设置PS1
cocktail@COCKTAILL7:~$ PS1="MAINTENANCE>>"
MAINTENANCE>>

* 设置颜色

第四章 通过shell进行数学运算
bash shell环境中,可以利用let, (())和[]执行基本的算术操作符。
expr和bc可以用于高级算术操作。

#!/bin/bash
no1=5
no2=5

#let 
 使用let命令,变量名前不需要加$
let result=no1+no2
echo $result
let no1++
echo "no1++ $no1"
let no2--
echo "no2-- $no2"
let ++no1
echo "++no1 $no1"
let --no2
echo "--no2 $no2"
let result=no1+no2
echo $result

#[] 
result1=$[ no1 + no2 ]
echo $result1

#[] 
result2=$[ $no1 +5 ]
echo $result2

#(())
result3=$(( no1 +45 ))
echo $result3

#expr 
result=`expr 3 + 4`
result=$(expr $no1 + 5)

#bc 
echo "4 * 0.56" | bc

no=54
result5=`echo "$no * 1.5" | bc`
echo $result

#bc scale  设置小数点精度
echo "scale=3;3/8" | bc

#bc obase ibase  进制转换
no=100
echo "obase=2;$no" | bc

no=1100110
echo "obase=10;ibase=2;$no" | bc

#bc sqrt 计算平分和平分根
echo "sqrt(100)" | bc
echo "10^10" | bc

第五章 玩转文件描述符和重定向
  文件描述符是与文件输入,输出相关联的整数,他们用来跟踪已打开的文件,最常见的文件描述符是stdin, stdout, stderr。 我们可以将某个文件描述符的内容重定向到另一个文件描述符中。
  0  stdin 标准输入
  1  stdout 标准输出
  2  stderr 标准错误

> 等同于 1>   >> 等同于 1>>

命令执行成功与否的情况
当一个命令发生错误并退回时,它会返回一个非0的退出状态,而当命令成功完成之后,它会返回数字0.
退出状态可以从特殊变量 $? 中获得(在命令执行语句之后运行echo $? ,就可以打印出退出状态)


标准错误和标准输出分别输出到不同文件
  cmd 2>stderr.txt 1>stdout.txt
将标准错误和标准输出一起输出到同一文件
  cmd 2>&1 output.txt
或者
  cmd &> output.txt

/dev/null 是一个特殊设备文件,这个文件接收到任何数据都会被丢弃,因此null设备通常也被称为位桶(bit bucket)或者黑洞
some_command 2> /dev/null

tee命令 一方面将数据重定向到文件,另一方面还可以提供一份重定向数据副本作为后续命令的stdin
command | tee file1 file2
cat debug* | tee out.txt | cat -n
tee命令的-a参数,可以设置追加文本
cat debug* | tee -a out.txt | cat -n

我们可以使用stdin作为命令参数,只需要将-作为命令的文件名参数即可,例如
echo who is this | tee -
或者将/dev/stdin作为输出文件名来使用stdin
类似地,使用/dev/stderr代表标准错误,/dev/stdout代表标准输出。

1.5.3补充内容
1,将文件重定向到命令
cmd < file
2,重定向脚本内部的文本块
cat <<EOF>log.txt与下一个EOF之间的所有文本都会当做stdin, 输出到log.txt中
#!/bin/bash

cat <<EOF>log.txt
LOG file header
this is a test log file
function system statistics
EOF


3,自定义文件描述符
文件描述符是用于访问文件的一种抽象指针,
我们可以使用exec命令创建自定义的文件描述符,
文件打开模式,通常有三种模式,
* 只读模式
* 截断模式
* 追加模式
< 操作符用于从文件中读取到stdin
> 操作符用于截断模式的文件写入(数据在目标文件内容被截断之后写入)
>> 操作符用于追加模式的文件写入(数据被添加到文件的现有内容中,而且该目标文件中原有的内容不会丢失)

文件描述符可以用以上三种模式中的任意一种来创建,例如
为读取文件创建一个文件描述符  $ exec 3
** 分配文件描述符3 给input.txt 用于从文件中读取信息。
maintenance>PS1="maintenance> "
maintenance> echo this is a test line > input.txt
maintenance> exec 3maintenance> cat <&3
this is a test line


** 创建文件描述符用于写入到文件中(截断模式)
maintenance> exec 4>output.txt
You have new mail in /var/mail/cocktail
maintenance> echo newline >&4
maintenance> cat output.txt
newline

这两种方式都把文本写入到了output.txt文件中。区别在哪??????
maintenance> echo xxxoo > output.txt
maintenance> cat output.txt
xxxoo


** 创建文件描述符用于追加写入 (追加模式)
maintenance> exec 5>>input.txt
maintenance> echo appended line >&5
maintenance> cat input.txt
this is a test line
appended line

每次创建文件描述符,使用之后,需要用exec再重新创建


第六章 数组和关联数组
bash支持普通数组和关联数组
普通数组:只能用整数作为数组索引
关联数组:可以使用字符串作为数组索引

普通数组
   定义数组的方式:
   1  array=(1 2 3 4 5)
   2  array[0]="text1"
      array[1]="text2"
      array[2]="text3"
      array[3]="text4"

  打印数组元素
   echo ${array[0]}  输出一个元素
   echo ${array[*]}  输出数组中所有值
   echo ${array[@]}  输出数组中所有值
   echo $(#array[*]) 打印数组长度

关联数组
  定义关联数组为水果制订价格
  declare -A fruite_value
  fruite_value=([apple]='100' [orange]='150')
  或者
  fruite_value[apple]='100'
  fruite_value[orange]='150'

  列出数组索引
  获取索引列表  echo${!fruite_value[*]}


第七章 使用别名
别名可以使用函数实现,或者alias命令实现
例如  alias install='sudo apt-get install'

alias命令 的作用是暂时的,一旦关闭当前终端,设置的别名就失效了,
为了使别名一直保持效果,可以放入~/.bashrc文件中
echo 'alias install="sudo apt-get install"' >> ~/.bashrc

删除别名  用unalias 或者 从~/.bashrc中删除

另一种创建别名的方法时定义个函数,放入~/.bashrc
例如,创建一个别名rm,它能删除原始文件,并在backup目录中保存副本
alias rm='cp $@ ~/backup; rm $@'

1.7.3 补充
字符 \ 对命令实施转义,使我们可以执行原本的命令,而不是这些命令的别名替身。在不信任的环境下执行特权命令,通过在命令前加上 \ 来忽略可能存在的别名设置总是一个不错的安全实践,因为攻击者可能已经利用别名将某些特权命令替换成一些别有用心的命令,借此盗取用户输入的重要信息!


第八章 获取终端信息
  处理当前终端的行数,列数,光标位置,遮盖密码字段
  tput stty是两款终端处理工具,

  获取终端行数和列数
  mainenance> tput cols
  107
  mainenance> tput lines
  48
  mainenance> tput longname  获取当前终端名
  X11 terminal emulator   (X11终端模拟器)
  mainenance> tput cup 100 100
  将光标移到方位(100,100)处
  tput setb no  设置终端背景色  no可以在0-7之间取值
  mainenance> tput bold   设置终端粗体
  设置下划线
  mainenance> tput smul
  mainenance>
  mainenance> tput rmul
  mainenance>

  当输入密码时,不能让输入的内容显示出来,使用stty
  mainenance> cat stty.sh
  #!/bin/bash
  echo -e "enter password:"
  stty -echo
  read password
  stty echo
  echo
  echo Password read.
  选项-echo禁止将输出发送到终端,而选项echo则允许发送输出。

第九章 获取,设置日期和延时   UTC coordinated universal time
  在类unix系统中,日期被存储为一个整数,其大小为自世界标注时间 1970年1月1日0时0分0秒 起所流逝的秒数。

  读取日期
  mainenance> date
  Wed Feb 12 16:48:01 SGT 2014
  输出秒数
  mainenance> date +%s
  1392195142
  maintenance> date --date "Wed Feb 12 16:48:01 SGT 2013" +%s
  1360658881
  maintenance$ date --date "Wed Feb 12 16:48:01 SGT 2013" +%A
  Tuesday

日期格式字符串列表
2014-2-10,《linux <wbr>shell脚本攻略》学习笔记,第一章

timescriptpath命令
使用tputhesleep从0开始计数到40
#!/bin/bash
echo -n Count:
tput sc  # 存储光标当前位置,
count=0
while true
do
  if [ $count -lt 40 ];then
    let count++
    sleep 1
    tput rc  # 恢复光标位置  (恢复光标到行首,再删掉这行的内容,再打印count++)
    tput ed  # 清除从当前光标位置到行尾之间的所有内容
    echo -n $count
  else
    exit 0
  fi
done



第十章 调试脚本

bash -x script.sh  启动跟踪调试shell脚本
运行带有-x标志的脚本能打印出所执行的每一行命令以及当前状态。
-x标识将脚本中执行过得每一行都输出到stdout。不过,我们也可以要求只关注脚本某些部分的命令及参数的打印输出。针对这种情况,可以在脚本中使用set built-in来启动或者禁止调试打印

set -x 在执行时显示参数和命令
set +x 禁止调试
set -v 当命令进行读取时显示输入
set +v 禁止打印输入

#!/bin/bash
function DEBUG(){
  [ "$_DEBUG" == "on" ] && $@ || :
}

for i in {1..10}
do
  DEBUG echo $i
done

加上_DEBUG=on 调试信息才会打印出来, bash中, : 告诉shell不作任何操作。
_DEBUG=on bash ./debug1.sh

1.10.3 补充
shebang的妙用
#!/bin/bash -xv 如此这般,就可以启动调试功能


第十一章 函数和参数
定义函数:
function fname(){
  statements
}
或者
fname(){
  statements
}

#!/bin/bash
fname(){
  echo $1, $2
  echo "$@"
  echo "$*"
}
fname abc xxoo 123

$1 :第一个参数
$2 :第二个参数
$@ :"$1" "$1" "$1"
$* :"$1c$1c$1"  c是IFS的第一个字符

补充
1,递归函数
F(){ echo $1; F hello; sleep 1;}

Fork炸弹
:(){ :|:& };:

2,导出函数
函数也可以像环境变量那样用export导出,如此一来,函数的作用域可以扩展到子进程
export -f fname

3, 读取命令返回值
echo $?  获取命令或者函数的返回值(退出状态), 0表示成功退出,非0表示不成功退出。


第十二章 读取命令序列输出
ls | cat -n > out.txt

cmd_output=$(ls | cat -n)
cmd_output=`ls | cat -n`

补充
1,子shell : 用()操作符定义一个子shell
#!/bin/bash
pwd
(cd /bin; ls)
pwd


2,子shell
output=$(cat test.txt)
output=`cat test.txt`


第十三章 以不按回车键的方式读取字符 "n"

read命令  从键盘或者stdin 读取文件。

用法1: 从输入中读取n个字符并存入变量var
例如:read -n 2 var    
      echo $var
用法2:显示提示信息,stdin输入存入变量var
read -p "enter:" var 

用法3:用不回显的方式读取密码
read -s var   

用法4:在特定时间内读取输入。下面在5秒之内。
read -t 5 var

用法5:用定界符结束输入行
read -d delim_charvar
read -d ":" var


第十四章  字段你分隔符和迭代器
   CSV comma separated value 逗号分隔型的数值

   #!/bin/bash
   data="name,sex,rollno,location"
   oldIFS=$IFS
   IFS=,
   for item in $data
   do
     echo Item: $item
   done
   IFS=$oldIFS



第十五章 比较与测试
算术比较 -o 逻辑或  -a 逻辑与
逻辑判断 || 逻辑或  && 逻辑与


if和else语句条件判断部分会很长,可以用逻辑运算符使他变得简洁
[ condition ] && action  如果condition为真,则执行action
[ condition ] || action  如果condition为假,则执行action

例如:
#!/bin/bash
function DEBUG(){  
  [ "$_DEBUG" == "on" ] && $@ || :

}
for i in {1..10}
do
  DEBUG echo $i
done


算术比较
[ $var -eq 0 ] or [ $var -eq 0 ]
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于

多个条件进行测试
[ $var -eq 0 -a $var -gt 4 ]   逻辑与 -a   and
[ $var -eq 0 -o $var -gt 4 ]   逻辑或 -o   or


文件系统相关测试
2014-2-10,《linux <wbr>shell脚本攻略》学习笔记,第一章
2014-2-10,《linux <wbr>shell脚本攻略》学习笔记,第一章

-f   file
-x   executable
-d   directory
-e   exit

字符串比较
字符串比较最好采用双中括号
[[ $str1 = $str2 ]]         检查字符串相等
[[ $str1 == $str2 ]]        检查字符串相等
[[ $str1 != $str2 ]]        检查字符串不相等
[[ $str1 > $str2 ]]         比较字母序列
[[ $str1 < $str2 ]]        
[[ -z $str2 ]]              是空字符串
[[ -n $str2 ]]              是非空字符串


【Note: 等号前后各有一个空格,如果忘记加空格,就是赋值语句


使用test命令,可以避免括号过多
例如
if [ $var -eq 0 ]; then echo ...; fi
if test $var -eq 0; then echo ...; fi
1 0
原创粉丝点击