Linux Shell脚本攻略1:小试牛刀(3)

函数和参数
定义函数 
function fname() { statements }
fname() { statements }
调用函数 
fname;
参数可以传递给函数,并由脚本进行访问 
fname arg1 arg2
参数也可以传递给脚本并通过script:$0(脚本名)访问。 
$1是第一个参数。
$n是第n个参数。
"$@" 被扩展成"$1" "$2" "$3"等。
"$*" 被扩展成"$1c$2c$3",其中c是IFS的第一个字符。
"$@" 要比"$*"用得多。由于"$*"将所有的参数当做单个字符串,因此它很少被使用。
在Bash中,函数同样支持递归。 
F() { echo $1; F hello; sleep 1; }
Fork炸弹 
:(){ :|:& };:
导出函数 
函数也能像环境变量一样用export导出,如此一来,函数的作用域就可以扩展到子进程中,如:$ export -f fname
读取命令返回值,如果命令成功退出则返回状态为0,否则为非0。 
$ cmd; echo $?;
向命令传递参数。假设-p、-v是可用选项,-k N是另一个可以接受数字的选项,同时该命令还接受一个文件名作为参数,那么,它有如下几种执行方式: 
$ command -p -v -k 1 file
$ command -pv -k 1 file
$ command -vpk 1 file
$ command file -pvk 1
将命令序列的输出读入变量
输入通常是通过stdin或参数传递给命令。输出要么出现在stderr,要么出现在stdout。当我们组合多个命令时,通常将stdin用于输入,stdout用于输出。此时,这些命令被称为过滤器(filter),我们使用管道(pipe)连接每个过滤器,管道操作符是|。如: 
$ cmd1 | cmd2 | cmd3
我们通常使用管道并利用子shell的方式将多个文件的输出组合起来,如: 
$ ls | cat -n > out.txt
我们可以用下面的方法读取由管道相连的命令序列的输出,这种方法被称为子shell。 
$ cmd_output=$(COMMANDS)
$ cmd_output=$(ls | cat -n); echo $cmd_output;
另一种被称为反引用(也有人称反标记)的方法也可以用于存储命令输出: 
$ cmd_output=`COMMANDS`
$ cmd_output=`ls | cat -n`; echo $cmd_output;
利用子shell生成一个独立的进程,可以使用()操作符来定义一个子shell: 
$ pwd; (cd /bin; ls); pwd;
当命令在子shell中执行时,不会对当前shell有任何影响;所有的改变仅限于子shell内。
通过引用子shell的方式保留空格和换行符。假如我们使用子shell或反引用的方法将命令的输出读入一个变量中,可以将它放入双引号中,以保留空格和换行符\n。如: 

不使用回车键来读取n个字符
read是一个重要的Bash命令,它用于从键盘或标准输入中读取文本。我们可以使用read以交互的形式读取来自用户的输入。
大多数编程语言的输入库是从键盘读取输入,但只有按下回车键的时候,才标志着输入完毕。而read命令提供了一种不需要按回车键就可以读取输入的方法。
从输入中读取n个字符并存入变量variable_name: 
$ read -n number_of_chars variable_name
用无回显的方式读取密码 
$ read -s var
显示提示信息 
$ read -p "Enter input:" var
在特定时限内读取输入(s) 
$ read -t timeout var
用特定的定界符作为输入行的结束 
$ read -d delim_char var
运行命令直至成功
有时候命令只有满足某些条件或是某种外部事件(例如文件可以被下载)操作才能够成功执行,这种情况下,我们可能希望重复执行命令,直到成功为止。

    repeat() 
    {
    while true   
    # 大多数现代系统中,true是作为/bin中的一个二进制文件来实现的,因此每执行一次while循环,shell就会生成一个进程。不想这样的话,可以使用shell内建的:命令。
    do 
        $@ && return
    done 
    } 
1
2
3
4
5
6
7
8
    repeat() 
    {
    while :     # : 总是会返回为0的退出码,即成功执行命令的退出码。
    do 
        $@ && return
    done
    } 
1
2
3
4
5
6
7
    repeat() 
    {
    while true
    do
        $@ && return
        sleep 30    #访问网站的时候要控制频率,以防被加入黑名单。
    done 
    }  
1
2
3
4
5
6
7
8
字段分隔符
内部字段分隔符(Internal Field Separator,IFS)是shell脚本编程中的一个重要概念。在处理文本数据时非常重要。
内部字段分隔符适用于特殊用途的定界符(delimiter),IFS是存储定界符的环境变量,它是当前shell环境使用的默认定界字符串。
考虑CSV数据的情况:
    data="name,sex,rollno,location"
    oldIFS=$IFS
    for item in $data;
    do
        echo Item: $item
    done
    IFS=$oldIFS
1
2
3
4
5
6
7
    #!/bin/bash
    #用途:演示IFS的用法
    line="root:x:0:0:root:/root:/bin/bash"
    oldIFS=$IFS;
    IFS=":"
    count=0
    for item in $line;
    do
        [ $count -eq 0 ] && user=$item;
        [ $count -eq 0 ] && shell=$item;
        let count++
    done;
    IFS=$oldIFS
    echo $user\'s shell is $shell;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
迭代器
对一系列值进行迭代时,循环非常有用。Bash提供了多种类型的循环。

for循环
    for var in list;   #list可以是一个字符串,也可以是一个序列。
    do
        commands;
    done
1
2
3
4
echo {1..50}能够生成一个从1~50的数字列表。
echo {a..z}; echo {a..h};能够生成字母列表。
for i in {a..z}; do actions; done;
for循环也可以采用C语言中for循环的格式,如:

    for((i=0;i<10;i++))
    {
        commands;
    }
1
2
3
4
while循环
    while condition
    do
        commands;
    done
1
2
3
4
until循环
    x=0;
    until [ $x -eq 9 ];
    do
        let x++; echo $x;
    done
1
2
3
4
5
比较与测试
    if condition;
    then
        commands;
    else if condition; then
        commands;
    else
        commands;
    fi

    [ condition ] && action; #如果condition为真,则执行action;

    [ condition ] || action; #如果condition为假,则执行action。

    # &&是逻辑与运算发,||是逻辑或运算符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
算数比较
条件通常被放置在封闭的中括号内,一定要注意在[或]与操作数之间有一个空格,如果忘记了这个空格,脚本就会报错,例如: 
[$var -eq 0 ] or [ $var -eq 0]
对变量或值进行算术条件判断: 
[ $var -eq 0 ] #当$var等于0时,返回真
[ $var -ne 0 ] #当$var为非0时,返回真
[ $var -gt 0 ] #当$var大于0时,返回真
[ $var -lt 0 ] #当$var小于0时,返回真
[ $var -ge 0 ] #当$var大于等于0时,返回真
[ $var -le 0 ] #当$var小于等于0时,返回真
可以结合多个条件进行测试 
[ $var1 -ne 0 -a $var2 -gt 2 ] #使用逻辑与-a
[ $var1 -ne 0 -o $var2 -gt 2 ] #使用逻辑或-o
文件系统相关测试

[ -f $file_var ] # 如果给定的变量包含正常的文件路径或文件名,则返回真。
[ -x $var ] # 如果给定的变量名包含的文件可执行,则返回真。
[ -d $var ] # 如果给定的变量包含的是目录,则返回真。
[ -e $var ] # 如果给定的变量包含的文件存在,则返回真。
[ -c $var ] # 如果给定的变量包含的是一个字符设备文件的路径,则返回真。
[ -b $var ] # 如果给定的变量包含的是一个块设备文件的路径,则返回真。
[ -w $var ] # 如果给定的变量包含的文件可写,则返回真。
[ -r $var ] # 如果给定的变量包含的文件可读,则返回真。
[ -L $var ] # 如果给定的变量包含的是一个符号链接,则返回真。
fpath="/etc/passwd"
if [ -e $fpath ]; then
    echo File exists;
else
    echo Does not exist;
fi
1
2
3
4
5
6
字符串比较 
使用字符串比较时,最好用双中括号,因为有时候采用单个中括号会产生错误。
[[ $str1 = $str2 ]] :当str1等于str2时,返回真,也就是说,str1和str2包含的文本是一模一样的。
[[ $str1 == $str2 ]]:这是检车字符串是否相等的另一种写法。
[[ $str1 != $str2 ]]:如果str1和str2不相同,则返回真。
[[ $str1 > $str2 ]] :如果str1的字母序比str2大,则返回真。
[[ $str1 < $str2 ]] :如果str1的字母序比str2小,则返回真。
[[ -z $str1 ]] :如果str1包含的是空字符串,则返回真。
[[ -n $str1 ]] :如果str1包含的是非空字符串,则返回真。
    if [[ -n $str1 ]] &&[[ -z $str2 ]];
    then
        commands;
    fi
1
2
3
4
    str1="Not empty "
    str2=""
    if [[ -n $str1 ]] && [[ -z $str2 ]];
    then
        echo str2 is nonempty and str2 is empty string.
    fi
1
2
3
4
5
6
test命令可以用来执行条件检测
    if [ $var -eq 0 ]; then echo "True"; fi
    # 也可以写成:
    if test $var -eq 0; then echo "True"; fi
————————————————

原文链接:https://blog.csdn.net/qixizhuang/article/details/77918786

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值