⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bash编程笔记.txt

📁 linux shell bash 编程
💻 TXT
字号:
Bash特殊字符
 
*:匹配任何字符串 
?:匹配任何单个字符 
[]: 集合运算符
[set]:用字符集合作通配符匹配单个字符,如:[aeiou],[a-z],[a-h, w-z] 
[!set]:除了集合外的所有字符组成的集合作通配符 
< :输入重定向 
> :输出重定向(没有文件则创建,有则覆盖) 
>> :输出重定向(没有则创建,有则追加到文件尾部) 
(): 子shell
{}: 命令块 
| :管道 
\ :引用后面的单个字符 
' ': 强引用字符串,不解释特殊字符 
" " : 弱引用字符串,解释所有特殊字符 
` ` : 命令替换 
; : 命令分隔符(命令终止符),运行在一行里执行多条命令 
# :行注释 
$ :变量表达式 
& :在后台执行命令 

Bash的保留变量

$#: 表示脚本程序的命令参数个数或函数的参数个数

$$: 表示当前脚本程序的进程号

$?: 表示脚本程序或函数的返回状态值,正常为 0,否则为非零的错误号。

$*: 表示所有的脚本参数或函数参数

$@: 表示所有的参数, 一些用双引号括起来

$0, $1, $2, ... 
表示系统传给脚本程序或脚本程序传给函数的第0个、1个、2个等参数

${#param}: 表示param的长度.

变量赋值

1. BASH变量值从右到左

2. unset删除变量的值, set显示所有定义的变量

3. 变量替换
   
(1). ${var:-word}: 如果var存在且不为空,返回它的值,否则返回word
     echo $UNAME
     (变量值为空)
     echo hello ${UNAME:-world}
     hello world
     echo $UNAME
     (变量值为空, 未发生变化)
    
(2). ${var:=word}: 如果var存在且不为空,返回它的值,否则将word赋给var, 返回它的值 
     echo $UNAME
     (变量值为空)
     echo hello ${UNAME:-world}
     hello world
     echo $UNAME
     world     (变量值已发生变化)
    
(3). ${var:+word}: 如果var存在且不为空,返回word,否则返回空
     echo $VAR
     hello
     echo ${VAR:+world}
     world
     echo $VAR
     hello
     unset VAR
     echo ${VAR:+world}
    (变量值为空)   

(4). ${var:?word}: 如果var存在且不为空,返回它的值, 否则提示出错
     UNAME=
     echo ${UNAME:?}
     UNAME: parameter null or not set

(5). {var:offset[]}: 从offset位置开始返回var的一个长为length的子串, 
     若没有length,则默认到var串末尾
     UNAME=hello
     echo ${var:2:2}
     ll

5. Bash数组变量

   数组变量赋值有两种: 
  (1) name[index] = value 
  (2) name = (value1 ... valuen) 此时下标从0开始 

模式匹配

1. ${var#pattern}: 从var头部开始, 删除和pattern匹配的最短模式串, 
                   然后返回剩余串.

2. ${var##pattern}: 从var头部开始, 删除和pattern匹配的最长模式串, 
                    然后返回剩余串

3. ${var%pattern}: 从var尾部开始, 删除和pattern匹配的最短模式串, 
                  然后返回剩余串

4. ${var%%pattern}: 从var尾部开始, 删除和pattern匹配的最长模式串, 
                    然后返回 剩余串 

5. ${var/pattern/string}: 用string替换var中和pattern匹配的最长模式串.

   例如:
   MYVAR=`uname -n`
   echo $MYVAR
   qdcvs.gdc.lucent.com
   echo ${MYVAR#*.}
   gdc.lucent.com
   echo ${MYVAR##*.}
   com
   echo ${MYVAR%.*}
   qdcvs.gdc.lucent
   echo ${MYVAR%.*}
   qdcvs

Bash中条件和test命令

1. 测试条件: [ expression ] 或 test expression

2. 文件测试操作符
   -d file: file存在并且是一个目录 
   -e file: file存在 
   -f file: file存在并且是一个普通文件 
   -g file: file存在并且是SGID(设置组ID)文件 
   -r file: 对file有读权限 
   -s file: file存在并且不为空 
   -u file: file存在并且是SUID(设置用户ID)文件 
   -w file: 对file有写权限 
   -x file: 对file有执行权限,如果是目录则有查找权限 
   -O file: 拥有file 
   -G file: 测试是否是file所属组的一个成员 
   -L file: file为符号链接 
   file1 -nt file2: file1比file2新 
   file1 -ot file2: file1比file2旧 

2. 字符串操作符 

   str1=str2: str1和str2匹配 
   str1!=str2: str1和str2不匹配 
   str1<str2: str1小于str2 
   str1>str2: str1大于str2 
   -n str: str的长度大于0(不为空) 
   -z str: str的长度为0(空串) 

3. 整数操作符 

   var1 -eq var2: var1等于var2 
   var1 -ne var2: var1不等于var2 
   var1 -ge var2: var1大于等于var2 
   var1 -gt var2: var1大于var2 
   var1 -le var2: var1小于等于var2 
   var1 -lt var2 var1小于var2 

4. 逻辑操作符 

   !expr 对expr求反 
   expr1 && expr2 对expr1与expr2求逻辑与,当expr1为假时不再执行expr2 
   expr1 || expr2 对expr1与expr2求逻辑或,当expr1为真时不再执行expr2 
   注:另一种逻辑操作符 逻辑与expr1 -a expr2 逻辑或expr1 -o expr2 

Bash流控制

1. if...then...else

   if [ expression ]
   then
     statments
   fi 
   或者 
   if [ expression ]
   then
     statments
   else
     statments
   fi 
   或者 
   if [ expression ]
   then
     statments
   elif [ expression ]
  then
    statments
  else
    statments
   fi 

  例如:
   #!/bin/bash 

   if [ $1 -gt 90 ] 
   then 
     echo "Good, $1" 
   elif [ $1 -gt 70 ] 
     then 
       echo "OK, $1" 
     else 
       echo "Bad, $1" 
   fi 

   exit 0 

2. for...do...done

   for $var in [list]
   do
     statments
   done 

   例如:
   #!/bin/bash 

   for day in Sun Mon Tue Wed Thu Fri Sat 
   do 
    echo $day 
   done 

3. while...do...done

   while [ condition ]
   do
     statments
   done 

4. until...do...done
   until [ condition is TRUE ]
   do
     statments
   done 

5. case
   case "$var" in
   condition1 )
      statments1;;
   condition2 )
     statments2;;
   ...
   * )
     default statments;;
   esac 

   例如:

   #!/bin/bash 

   echo "Hit a key, then hit return." 
   read Keypress 

   case "$Keypress" in 
    [a-z] ) echo "Lowercase letter";; 
    [A-Z] ) echo "Uppercase letter";; 
    [0-9] ) echo "Digit";; 
    * ) echo "Punctuation, whitespace, or other";; 
   esac 

   exit 0 

Bash函数

1. 函数定义
function my_funcname { 
 code block
} 

或者 

my_funcname() { 
 code block
} 

2. 如何给函数传递参数和获得返回值

在函数被调用时用 BASH 的保留变量 $1 $2 ... 来引用参数, BASH 的返回值
可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的
返回一个返回值,则返回值就是该函数最后一条语句执行的结果
(一般为 0,如果执行失败返回错误码)。函数的返回值在调用该函数的程序体中
通过$?保留字来获得.

例如:

#!/bin/bash 

square() { 
 let "res = $1 * $1" 
 return $res 
} 

square $1 
result=$? 
echo $result 

命令行处理

命令行处理命令:getopts 
有两个参数,第一个为字母和冒号组成的选项列表字符串,第二个为一个变量名 
选项列表字符串以冒号开头的选项字母排列组成,如果一选项需要一个参数则该
选项字母后跟一个冒号 getopts分解第一参数,依次将选项摘取出来赋给第二个参数变量 
如果某选项有参数,则读取参数到内置变量OPTARG中 
内置变量OPTIND保存着将被处理的命令行参数(位置参数)的数值 
选项列表处理完毕getopts返回1,否则返回0.

例如: 
while getopts ":xy:z:" opt 
do 
case $opt in 
x) xopt='-x set';; 
y) yopt="-y set and called with $OPTARG";; 
z) zopt="-z set and called with $OPTARG";; 
\?) echo 'USAGE: getopts.sh [-x] [-y arg] [-z arg] file…'
exit 1 
esac 
done 
shift ($OPTING-1) 
echo ${xopt: -'did not use -x'} 
echo ${yopt: -'did not use -y'} 
echo ${zopt: -'did not use -z'} 

echo 'Remaining command-line arguments are :'
for f in '$@' 
do 
echo -ee "\t$f\n"
done 

进程和作业控制 

信号处理命令:trap 
格式:trap command sig1 sig2 … 
sig可以为中断(Ctrl+c)、挂起(Ctrl+z)等,可以使用kill -l查看信号清单 
当脚本接受到信号sig1、sig2等,trap就执行命令command,command完成后脚本重新执行 
信号可以通过名称或数字来标识 

作业控制命令:bg、fg 
bg:显示后台进程,即用Ctrl+z挂起或'命令 &'执行的进程 
fg:将后台进程转到前台执行 
kill -9 %n:杀掉第n个后台进程 

正则表达式

^: 匹配行首
$: 匹配行尾
*: 一个单字符后紧跟*,匹配0个或多个此单字符
[ ]: 匹配[ ]内字符。可以是一个单字符,也可以是字符序列。
      可以使用- 表示[ ]内字符序列范围,
      如用 [1-5]代替[1 2 3 4 5]
\: 用来屏蔽一个元字符的特殊含义。特殊字符:$ . ' " [ ] ^ ( ) | \ + ? *
.: 匹配任意单字符
pattern\{n\}: 用来匹配前面pattern出现次数。n为次数
pattern\{n,\}:  含义同上,但次数最少为n
pattern\{n, m\}: 含义同上,但pattern出现次数在n与m之间

注: ^直接用在第一个括号里,意指否定或不匹配括号里内容。
如:[ ^ 0 - 9 ] 匹配任一非数字型字符。

find

1. 在当前目录及子目录中查找所有的"*.txt"文件
    find ~ -name "*.txt" -print
2. 按照文件权限模式来查找文件
   find . -perm 755 -print
3. 希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找
   find /apps -name "/apps/bin" -prune -o -print
4. 在/apps目录下查找属于accts用户组的文件
   find /apps -group accts -print
5. $HOME目录中查找文件属主为dave的文件
   find ~ -user dave -print
6. 在系统根目录下查找更改时间在5日以内的文件
   find / -mtime -5 -print
   在/var/adm目录下查找更改时间在3日以前的文件
   find /var/adm -mtime +3 -print
7. 查找更改时间比文件age.awk新但比文件belts.awk旧的文件
   find . -newer age.awk ! -newer belts.awk -exec ls -l {} \
8. 在当前目录下查找除目录以外的所有类型的文件
   find . ! -type d -print
9. 在当前目录下查找文件长度大于1M字节的文件
   find . -size +1000000c -print
   当前目录下查找长度超过10块的文件
   find . -size +10 -print
   
10. 在当前目录下查找以pdf结尾并删除之
   find . -name "*.pdf" -print | xargs rm 

   note: 使用exec和xargs可以使用户对所匹配到的文件
   执行几乎所有的命令

grep

-c: 输出匹配行的计数
-n: 显示匹配行及行号
-i: 不区分大小写
-v: 显示不包含匹配文本的所有
ls -l | grep '^[^d]'
egrep可以以一个文件作为保存的字符串

sed 

1. sed将数据拷贝到一个编辑缓冲区, 按行编辑
2. []表示空格, [ ]表示tab键
's/\.$//g':  删除以句点结尾行
'-e /abcd/d': 删除包含a b c d的行
's/[][][]*/[]/g': 删除一个以上空格,用一个空格代替
's/^[][]*//g': 删除行首空格
's/\.[][]*/[]/g': 删除句点后跟两个或更多空格,代之以一个空格
'/^$/d': 删除空行
's/^.//g' 删除第一个字符
's/COL\(...\)//g: 删除紧跟C O L的后三个字母
's/^\///g': 从路径中删除第一个\
's/[]/[ ]//g': 删除所有空格并用t a b键替代
'S/^[ ]//g': 删除行首所有t a b键
's/[ ]*//g':  删除所有t a b键
3. 去除行尾^M字符
  sed 's/\^M//g' dos.txt

awk

1. awk执行时,其浏览域标记为$1,$2...$n, $0, 所有域
   awk 'print {$1, $4}' grade.txt
   显示学生名字和成绩
2. awk 'BEGIN {print "name--------"}{print $1}{"EOF"}' grade.txt
3. -F指定域分隔符
   ARGC: 命令行参数个数
   ARGV: 命令行参数排列
   ENVIRON: 支持队列中系统环境变量的使用
   FILENAME: awk浏览的文件名
   FNR: 浏览文件的记录数
   FS:  设置输入域分隔符,等价于命令行-F选项
   NF: 浏览记录的域个数
   NR: 已读的记录数
   OFS: 输出域分隔符
   ORS: 输出记录分隔符
   RS: 控制记录分隔符
    
   echo $PWD | awk -F/ '{print $NF}'

4. awk条件操作符
   <: 小于 
   >=: 大于等于
   <=: 小于等于
   ~: 匹配正则表达式
   ==: 等于
   !~: 不匹配正则表达式
   !=: 不等于

   awk '{if ( $0 ~ /brown/) print $4;}' grade.txt
   awk '{if ( $1=="brown" && $3="F" ) print $0;}' grade.

cut, sort, join,uniq

1. cut用来从标准输入或文本文件中剪切列或域.
   -d 指定与空格和tab键不同的域分隔符
   cut -d: -f1,3 grade.txt
2. sort参照第一个域作为域0,域1是第二个域
   -t 域分隔符;用非空格或tab键分隔域。
   sort -t: video.txt
   sort -t: -r video.txt(分类求逆)
   sort -t: +1 video.txt(按分类键1进行分类)
   sort -t: +1n video.txt(-n按数值进行分类)
   sort -t: video.txt(去除重复)
3. uniq用来从一个文本文件中去除或禁止重复行
4. join用来将来自两个分类文本文件的行连在一起

提示

1. << :输入重定向(here文档) 
格式: command << label 
input… 
label 

例如:

echo "auto ftp a file" 
USER=jx
PASS=123456 
ftp -i -n <<END
open stein.telica.com 
user $USER $PASS 
bin
cd /cvs/cvsroot/Repository/CVSROOT
get val-tags
close 
END

2. read 函数来实现读取用户输入

例如:

#!/bin/bash

echo Please enter your name
read NAME 
echo "Hi! $NAME !"

3. crontab

格式:
分 时 日 月 星期  命令(绝对路经)

例如:

30 21 * * * /usr/local/bin/cleanup.sh
每晚21:30运行/usr/local/bin/cleanup.sh

crontab -l -e -r
-e: 编辑crontab文件
-l: 列出crontab文件
-r: 删除crontab文件

4. 标准输入:(stdin, 0)
   标准输出:(stdout, 1)
   标准错误出:(stderr, 2)

find /home -name lost* > all_result 2>&1
将标准错误输出也重定向到标准输出中,再将标准输出重定向到 all_result 这个文件中

find /home -name lost* 2> /dev/null
避开众多无用出错信息的干扰

5. shift 
   shift [N]: 左移位置变量N.

   例如:

   $1="one" $2="two" $3="three", $4="four"
   shift 2
   then $1="three" $2="four"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -