shell 脚本备忘录

来源:互联网 发布:mac ppt软件 编辑:程序博客网 时间:2024/06/09 21:17

SHELL内部参数
$#        ----传递给程序的总的参数数目
$?       ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。
$*       ----传递给程序的所有参数组成的字符串。
 $-      ----在Shell启动或使用set命令时提供选项
 $?      ----上一条命令执行后返回的值
 $$      ----当前shell的进程号
 $!      ----上一个子进程的进程号(若这空表示进程已结束)
 $@      ----所有的参数,每个都用双括号括起
 $n      ----位置参数值,n表示位置
 $0      ----当前shell名

-------------------------------------------------------------------------------------

SHELL 判断是否为数字 【转】
## 方法2, 可以,不过不是bash实现的,是使用了grep的正则
#if grep '^[[:digit:]]*$' <<< "$1";then
#    echo "$1 is number."
#else
#    echo 'no.'
#fi
    
## 方法3
#if "$1" -gt 0 2>/dev/null ;then
#    echo "$1 is number."
#else
#    echo 'no.'
#fi
    
## 方法4,case
#case "$1" in
#    [1-9][0-9]*) 
#        echo "$1 is number."
#        ;;
#    *)  
#        ;;
#esac
    
## 方法5,awk
#echo $1| awk '{print($0~/^[-]?([0-9])+[.]?([0-9])+$/)?"number":"string"}'
    
## 方法5,awk
#if [ -n "$(echo $1| sed -n "/^[0-9]\+$/p")" ];then
#    echo "$1 is number."
#else
#    echo 'no.'
#fi
    
 ## 方法6,expr
expr $1 "+" 10 &> /dev/null
if [ $? -eq 0 ];then
    echo "$1 is number"
else
    echo "$1 not number"
fi


#####判断是否为汉字

#!/bin/bash
LC_ALL=C
[[ $1 != *[[:alnum:]]* && $1 != *[[:punct:]]* ]] && echo hanzi || echo string

------------------------------------------------------------------------------------

一些算术括展运算,如:
z=`expr $z + 2`等效于  z=$(($z + 2))  等效于 z=$((z + 2 ))
递增  let n=n+1 等效于 (( n +=1))
> abc.txt 等效于 touch abc.txt
重定向
& > a.txt 将标准输出(屏幕)与错误输出重定向到a.txt
2>&1 stderr 重定向到stdout
&-  关闭输出
--------------------------------
匹配空格/去空格
sed 's/[[:space:]]*$//' <<< $content_answer
----------------------------------------
注意:写SHELL程序时,赋值前后不能有空格
---------------------------------------------------------
$! 运行在当前系统的最后一个PID(为空,表示进程已结束)

$$ 当前程序或脚本的PID

$@  接受传来的所有参数(数组),如下:
[root@jet tmp]# cat f.sh
#!/bin/bash
echo "$@"
shift
echo "$@"
[root@jet tmp]# bash f.sh 1 2 3 4 5
1 2 3 4 5  <--打印所有参数
2 3 4 5   <--经过shift后,向前娜了一个参数位

$# 得到变量值长度(记录参数的个数,一般用来检查某脚本要求传进参数的个数),如下
[root@jet tmp]# cat f.sh
#!/bin/bash
stringZ="aafafkjflkaflhgkhglsg"
echo ${#stringZ}
echo `expr length $stringZ`    <--可man expr 查看expr其它用法


数组
arr_string="a b c d e"
for i in ${arr_string[@]}      <----${arr_string[@]} 实际是数组
do
echo $i
echo $arr_string[5] <-----打印指定元素
done
echo ${#arr_string[@]}         <-----数组的元素的 个数 等于${#arr_string[*]} 输出 5 数组个数
echo ${arr_string[@]:0}        打印出数组的全部元素
echo ${arr_string[@]:1}        打印出数组的从第二个元素开始以后的全部元素 输出  b c d e
echo ${arr_string[@]:1:3}     打印出数组的从第二个到第四个元素 打印出 b c d

函数中传送数组并获取(数组参数)
function dis()
{
echo $@
}

str="how are you"
dis 123 $str

增加数组元素的个数
arr=( a  b c d e f )
arr=("${arr[@]}" "g")
echo ${arr[@]}     <-- 得到  a b c d e f g

[!a-zA-Z]  感叹号的意思为匹配 a-z 或A-Z
[^a-zA-Z]  ^的意思是排除a-z ,A-Z

------------------------------------------------------
一些特殊字符
;
命令分隔符,可以用来在一行中来写多个命令.
--------------------------------------------
;;
终止"case"选项.
--------------------------------------------
:
什么也不做,常用来做死循环如
#!/bin/bash
while :
do
echo aaaa
done

: > a.txt 与 cat /dev/null > a.txt 效果相同,都会将文本内容清空,但:属于内建命令,
--------------------------------------------
** 幂运算  如 let "b=2**3"; echo $b
% 取模  expr 5 % 3
+=      let "var += 5"; echo $var
-=
*=
/=

自加,自减一些写法
let "n = n + 1" 或 let "n++"  或 ((n++)) 或 :$((n++)) 或:$[ n++ ]
--------------------------------------------
浮点数比较
 if [ $(echo "$mya <=4.00" |bc) = 1 ] ; then echo ok; f
------------------------------------------
~+  相当于$PWD 变量

I/O重定向

cat {file1,file2,file3} > file4  将file1,file2,file3连接起来重定向到file4中

------------------------------------------------------------------------
从标准输入中得到数据
read -p "please enter the number :" num   <-----num 为变量
read -s num      <----不显示输入的字符
 ---------------------------------------------
#!/bin/bash
FILE=/etc/passwd
{
read line1
read line2
}< $FILE
echo $line1
echo $line2
-----------------------------------------------
command >&2 重定向 command 的 stdout 到 stderr
-----------------------------------------------
\<,\>
正则表达式中的单词边界.如:
bash$grep '\<the\>' textfile
----------------------------------------------
echo 后跟的一些参数
-n 在一行输出,不换行
----------------------------------------------
类似加法写法,小心
[jet@jet tmp]$ b=9
[jet@jet tmp]$ b+=5
[jet@jet tmp]$ echo $b
95
[jet@jet tmp]$ b=$b+5
[jet@jet tmp]$ echo $b
95+5
[jet@jet tmp]$ c=5
[jet@jet tmp]$ c=`expr $c + 5` <--- 这才是加法
[jet@jet tmp]$ echo $c
10
[jet@jet tmp]$ a=16+5
[jet@jet tmp]$ echo $a
16+5
[jet@jet tmp]$ let a=16+5   <---也可以用 let赋值
[jet@jet tmp]$ echo $a
21
[jet@jet tmp]$ let "b += 1"  <---也可以用 let赋值
[jet@jet tmp]$ echo $b
2
-------------------------------------------------
$(command) 与`command` 相等,作用效果一样
-------------------------------------------------
Bash 变量是不分类型的
   不像其他程序语言一样,Bash 并不对变量区分"类型".本质上,Bash 变量都是
.
但是依赖于上下文,Bash 也允许比较操作和算术操作.决定这些的关键因素就是,变量中的值
是否只有数字.

---------------------------------------------------
关于函数请求的变量
可用$1,$2.....$9 ,但是,当变量的个数大于9时应该这样表示${10}
#!/bin/bash
function c(){
   echo v1 is "$1"
   echo v2 is "$2"
   echo v3 is "$3"
   echo v4 is "$4"
   echo v5 is "$5"
   echo v6 is "$6"
   echo v7 is "$7"
   echo v8 is "$8"
  echo v9 is "$9"
  echo v10 is "${10}"
}
c 1 2 3 4 5 6 7 8 9 10 <--调用
-------------------------------------------------------
shift
shift 命令重新分配位置参数,其实就是向左移动一个位置.
$1 <--- $2, $2 <--- $3, $3 <--- $4, 等等.
老的$1 将消失,但是$0(脚本名)是不会改变的.如果你使用了大量的位置参数,那么
shift 命令允许你存取超过 10 个参数.虽然{}表示法也允许这样.
#!/bin/bash
until [ -z "$1" ]
do
 echo "$1"
shift    <---将参数向前移
done
exit
[jet@jet tmp]$ bash c.sh 1 2 3 4 5 6 7
1
2
3
4
5
6
7
----------------------------------------------------
 转义
对于特定的转义符的特殊的含义
在 echo 和 sed 中所使用的
\n 意味着新的一行
\r 回车
\t tab 键
\v vertical tab(垂直 tab),查前边的 Ctl-K
\b backspace,查前边的 Ctl-H
\a "alert"(如 beep 或 flash)
\0xx 转换成 8 进制 ASCII 解码,等价于 oxx
------------------------------------------------------
test  命令用法
if [ -z  "$1" ] 等价于 if test -z "$1"
-----------------------------------------------------
关于定义的是数组还是字符串区分
[root@jet script]# arr_string2="a b c d e"  <--这是字符串
[root@jet script]# echo ${#arr_string2[@]}
 1
   [root@jet script]# arr_string=(a b c d e)  《---这才是数组,用括号的
                [root@jet script]# echo ${#arr_string[@]}  <--------数组长度
                5
  [root@jet script]# echo ${arr_string[@]:0}  <-------- 所有数组的值
  a b c d e
  [root@jet script]# echo ${arr_string[@]:1}  <--------从下标是1起到最后
  b c d e
  [root@jet script]# echo ${arr_string[@]:1:3}   <--------从下标为1到3数组的值
  b c d


----------------------
二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别.
整数比较
-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]
<   小于(需要双括号),如:(("$a" < "$b"))
<=  小于等于(需要双括号),如:(("$a" <= "$b"))
>   大于(需要双括号),如:(("$a" > "$b"))
>=  大于等于(需要双括号),如:(("$a" >= "$b"))
bc计算
correct_rate=$(echo "scale=2;$Right/$have_done" | bc)

[root@jet script]# aaa=$(echo 'scale=2;(58.3+26.566)/35.4' | bc)
[root@jet script]# echo $aaa
2.39
[root@jet script]# bc <<< $(echo 'scale=2;(58.3+26.566)/35.4')  <-----------另一种写法
2.39
字符串比较
= 等于,如:if [ "$a" = "$b" ]
== 等于,如:if [ "$a" == "$b" ],与=等价
   注意:==的功能在[[]]和[]中的行为是不同的,如下:
    [[ $a == z* ]]  # 如果$a 以"z"开头(模式匹配)那么将为 true
   [[ $a == "z*" ]] # 如果$a 等于 z*(字符匹配),那么结果为 true
  [ "$a" == "z*" ] # 如果$a 等于 z*(字符匹配),那么结果为 true
           一点解释,关于 File globbing 是一种关于文件的速记法,比如"*.c"就是,再如~也是.
           但是 file globbing 并不是严格的正则表达式,虽然绝大多数情况下结构比较像.
   如[ $a == z* ] # File globbing 和 word splitting 将会发生
!= 不等于,如:if [ "$a" != "$b" ]这个操作符将在[[]]结构中使用模式匹配.
> 小于(大于也是一样),在 ASCII 字母顺序下.如:
 if [[ "$a" < "$b" ]]
 if [ "$a" \< "$b" ] 注意:在[]结构中"<"需要被转义.

 

逻辑操作(&& ||
写法如下:
if [ $condition1 ] && [ $condition2 ] 或 if [ $condition1 -a $condition2 ] 或 if [[ $condition1 && $condition2 ]]
注意; && || 不能出现在[...] 中
if [ $condition1 ] || [ $condition2 ] 或 if [ $condition1 -o $condition2 ] 或 if [[ $condition1 || $condition2 ]]
-------------------------------------------------------------------------------
sed 返回行号
sed "/查找内容/"q  file.txt | sed -n '$='

--------------------------------------------------------------------
, 逗号操作符
逗号操作符可以连接 2 个或多个算术运算.所有的操作都会被执行,但是只有最后一个操作作为结果.
[jet@jet tmp]$ let "t1 = ((5 + 3 , 7 + 2, 45 - 5 ))"; echo $t1
40
 let "t2 = ((a = 9, 15 / 3))" --->过程为: 把9賦值給a ,然后根据逗号操作符,把第最后一个值給t2
-------------------------------------------------------------------------------
将数组的值全部输出
echo ${PIPESTATUS[@]}
--------------------------------------------------------------------------
、获取数组元素的个数:
        array=(bill   chen  bai   hu)     //一定要用括号
        num=${#array[@]}                          //获取数组元素的个数。
-------------------------------------------------------------------------------
得到字符串长度
shell> a=ABC
shell> expr length ${a[@]}
获取字符串的长度:
       str="hello"
       len=${#str}
-------------------------------------------------------------------------------
几个内建PS参数
[jet@jet etc]$ echo $PS1
[\u@\h \W]\$
[jet@jet etc]$ echo $PS2
>
[jet@jet etc]$ echo $PS3
select 出来的提示符
[jet@jet etc]$ echo $PS4
+
---------------------------------------------------------------------------------
$PWD 与$OLDPWD
[jet@jet etc]$ echo $PWD
/etc
[jet@jet etc]$ cd ~
[jet@jet ~]$ echo $OLDPWD     <---上次操作所在的路径位置
/etc

---------------------------------------------------------------------------------
关于子串及字符串截取
格式;${string:position}
     ${string:position:length}

[root@jet tmp]# cat f.sh
#!/bin/bash
stringZ="abcABC123defDEF456"
echo '${stringZ:0} is :' .  ${stringZ:0}
echo '${stringZ:4} is :'.  ${stringZ:4}
echo '${stringZ:5:3} is :'.  ${stringZ:5:3}
echo '${stringZ: -4} is :'.  ${stringZ: -4}
echo '${stringZ:(-4)} is :'.  ${stringZ:(-4)}
[root@jet tmp]# bash f.sh
${stringZ:0} is : . abcABC123defDEF456 <-----此变量的所有串
${stringZ:4} is :. BC123defDEF456 <-----从正向索引为4开始截到最后(索引从0开始)
${stringZ:5:3} is :. C12 <-----从正向索引为5开始,向后截3位
${stringZ: -4} is :. F456 <-----反向截取4位(冒号和数字之间有空格)
${stringZ:(-4)} is :. F456 <-----反向截取4位(若不想用空格,可有括号)


expr substr $string $position $length
在 string 中从位置$position 开始提取$length 长度的子串.
[root@jet tmp]# a=abcABC123
[root@jet tmp]# expr substr $a 3 4
cABC   <------------从第三位起截4个
[root@jet tmp]# expr match "$a": "\([abc]\)"
a   <------------正则表达式截取
[root@jet tmp]# expr match "$a": "\(abc\)"
abc   <------------  正则表达式截取
[root@jet tmp]# expr match "$a": "\(aBc\)"
                     <------------正则表达式截取,因为不匹配,所以没有
[root@jet tmp]#


${string%substring}
从$string 的右边截掉第一个匹配的$substring
${string%%substring}
从$string 的右边截掉最后一个匹配的$substring

去除字符串后面的空格
  sed 's/[[:space:]]*$//' <<< $string
子串削除
${string#substring}   从$string 的左边截掉第一个匹配的$substring
${string##substring}   从$string 的左边截掉最后一个匹配的$substring
${string%substring}   从$string 的右边截掉第一个匹配的$substring
${string%%substring}   从$string 的右边截掉最后一个匹配的$substring
例:批量修改文件后缀
[root@jet abc]# ls
a.txt b.txt c.txt d.txt e.txt f.txt g.txt

[root@jet abc]# cat f.sh
#!/bin/bash
filename=`ls /tmp/abc`
for i in $filename
do
myleft=${i%%.txt}   <----截取后缀前面的部分
mv $i $myleft.TXT
done
批量修改文件名
#!/bin/bash
filename=`ls /tmp/abc`
for i in $filename
do
mv $i  `echo "$i"_bak`
done
[root@jet abc]# ls
a.TXT  b.TXT  c.TXT  d.TXT  e.TXT    f.TXT  g.TXT

子串替换
子串替换
${string/substring/replacement}    使用$replacement 来替换第一个匹配的$substring.
${string//substring/replacement}   使用$replacement 来替换所有匹配的$substring.
${string/#substring/replacement}   如果$substring 匹配以$string 的开头部分,那么就用$replacement 来替换$substring.
${string/%substring/replacement}   如果$substring 匹配以$string 的结尾部分,那么就用$replacement 来替换$substring.

[root@jet abc]# mystring=abcABC123abcABC123abc
[root@jet abc]# echo ${mystring/abc/xyz}
xyzABC123abcABC123abc
[root@jet abc]# echo ${mystring//abc/xyz}
xyzABC123xyzABC123xyz
[root@jet abc]# echo ${mystring/#abc/xyz}
xyzABC123abcABC123abc
[root@jet abc]# echo ${mystring/%abc/xyz}
abcABC123abcABC123xyz


-----------------------------------------------------------------------------------
循环
while [ 条件为真时 ]
do
.....
done

-----------------
filename="/a.txt"
while read line      <---line 为变量名,while read 每次读一行
do
.....
done < $filename
-----------------
until [ 条件为真时]
do
......
done
-----------------
case "变量" in
  条件1)
   command
;;
   条件2)
   command
;;
   *)           <----默认
  command
;;
esac
---------------------
循环控制
break         <---退出本层循环
break N    <----退出循环,默认N=1,表示退出本层循环,若N=2表示退出此层的上次循环
continue     <----结束本次循环,继续下次循环
continue N   <---结束N层循环,继续外层循环,与break N类似,只是继续下次循环  ,比较难懂,尽量少用
 #!/bin/bash
a="1 2 3 4 5 6"
b="11 22 33 44 55 66"
for i in ${a[@]}
do
        for bb in ${b[@]}
       do
          if [ "$bb" -eq 33 ] ; then
            continue      <----结束本次循环,继续下次循环
          elif [ "$i" -eq 5 ]; then
             break 2      <--退出for循环
          else
             echo $bb
            fi


       done

 echo $i

done
------------------------
here documnet如下:
cat << EOF > A.TXT    <--将下面的内容写到A.txt中
> AFLAFA
> AF
> AF
> AF
> AF
> AF
>
> EOF

here string
command <<< $a  <--$a 可理解为传递给command 要处理的内容,可同时传多个
------------------------------------------
局部变量的声明
在一个函数中,有时要用到局部变量,可用local来声明,如 local abc=555  
-----------------------------------------------------------
得到一个在后台运行的进程可用 pidof 进程名    ,若没有找到此进程号,则说明此进程此时没有运行

--------------------------------------
read命令 -n(不换行) -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显)
read -p "Enter your name:" name    #name 为变量

原创粉丝点击