zoukankan      html  css  js  c++  java
  • linux shell 脚本攻略学习2

    1.关于文件描述符和重定向:

    文件描述符是与一个打开的文件或数据流相关联的整数。文件描述符0、1以及2是系统预留的.

    0——stdin(标准输入)

    1——stdout(标准输出)

    2——stderr(标准错误)

    使用“echo $?”来显示状态

    amosli@amosli-pc:~/learn$ echo $?
    2
    amosli@amosli-pc:~/learn$ ls + 2> out.txt //没有任何输出,因为已经重定向到out.txt里面了
    amosli@amosli-pc:~/learn$ cat out.txt 
    ls: cannot access +: No such file or directory
    amosli@amosli-pc:~/learn$ cmd &> output.txt
    amosli@amosli-pc:~/learn$ cat output.txt 
    No command 'cmd' found, did you mean:
     Command 'dcmd' from package 'devscripts' (main)
     Command 'wmd' from package 'wml' (universe)
     Command 'amd' from package 'am-utils' (universe)
     Command 'tcmd' from package 'tcm' (universe)
     Command 'cme' from package 'libconfig-model-perl' (universe)
     Command 'cmp' from package 'diffutils' (main)
     Command 'qcmd' from package 'renameutils' (universe)
     Command 'mmd' from package 'mtools' (main)
     Command 'cm' from package 'config-manager' (universe)
     Command 'mcd' from package 'mtools' (main)
     Command 'icmd' from package 'renameutils' (universe)
     Command 'cad' from package 'rheolef' (universe)
    cmd: command not found

    cat a*  输出所有以a开头的文件的内容

    amosli@amosli-pc:~/learn$ cat a* | tee out.txt  | cat -n 
    cat: a1: Permission denied
         1    a1
         2    a1
    #上面的代码所说的是,tee命令接收到来扑克stdin的数据,它将stdout的一份副本写入文件out.txt,同时将另一份副本作为后续命令的stdin,命令cat -n 将从stdin中接收到的每行数据前加上行号并写入stdout
    
    amosli@amosli-pc:~/learn$ cat out.txt 
    a1
    a1
    amosli@amosli-pc:~/learn$ echo who is this |tee -
    who is this
    who is this

    自定义文件描述符:

    amosli@amosli-pc:~/learn$ exec 3<input.txt #为读取文件创建一个文件描述符
    bash: input.txt: No such file or directory 
    amosli@amosli-pc:~/learn$ echo this is a test line > input.txt
    amosli@amosli-pc:~/learn$ exec 3<input.txt
    amosli@amosli-pc:~/learn$ cat <&3 #使用自定义的文件描述3
    this is a test line

    文件打模式,一般有三种模式只读截断,和追加模式。

    <操作符用于从文件中读取至stdin中。>用于截断模式(个人理解即先清空文件里的内容,再写数据进去即为所谓的截断模式)。>>操作符用于追加模式的文件写入(数据被添加到文件的现有内容之后).

    2.数组和关联数组

    数组分为普通数组和关联数组,普通数组只能使用整数做索引,而关联数组可以使用字符串作为数组的索引。

    关联数组在很操作中相当有用,Bash4.0开始支持关联数组,4.0以前版本不支持关联数组!

    数组定义的方法:

    1)

    array=(1 2 3 4)

    2).array[index]=value;

    amosli@amosli-pc:~/learn$ array_var[0]="test1"
    amosli@amosli-pc:~/learn$ array_var[1]="test2"
    amosli@amosli-pc:~/learn$ array_var[2]="test3"
    amosli@amosli-pc:~/learn$ array_var[3]="test4"
    amosli@amosli-pc:~/learn$ echo ${array_var[0]}
    test1
    amosli@amosli-pc:~/learn$ echo ${array_var[1]}
    test2
    amosli@amosli-pc:~/learn$ echo ${array_var[2]}
    test3
    amosli@amosli-pc:~/learn$ echo ${array_var[3]}
    test4
    amosli@amosli-pc:~/learn$ echo ${array_var[4]}
    5
    amosli@amosli-pc:~/learn$ index=5;
    amosli@amosli-pc:~/learn$ echo ${array_var[$index]}
    6

    以清单方式列出所有数组的值:index使用*来进行匹配

    amosli@amosli-pc:~/learn$ echo ${array_var[*]}
    test1 test2 test3 test4 5 6

    也可以使用@符号来做index 

    amosli@amosli-pc:~/learn$ echo ${array_var[@]}
    test1 test2 test3 test4 5 6

    定义关联数组:

    首先,需要使用单独的一个变量名声明为关联数组,声明语句如下:

    declare -A ass_array

    (1) 内嵌索引-值列表法,提供一个索引-值列表

     ass_array=([index1]=value1 [index2]=value2)

    (2)独立的索引-值进行赋值

    ass_array[index1]=value1
    ass_array[index2]=value2

    举例:

    amosli@amosli-pc:~/learn$ declare -A fruits_value
    amosli@amosli-pc:~/learn$ fruits_value[apple]="apple is 5 dollars"
    amosli@amosli-pc:~/learn$ fruits_value[pear]="pear is 3 dollars"
    amosli@amosli-pc:~/learn$ echo ${fruits_value[apple]}
    apple is 5 dollars

    列出数组索引:

    amosli@amosli-pc:~/learn$ echo ${!fruits_value[*]}#方法1
    apple pear
    amosli@amosli-pc:~/learn$ echo ${!fruits_value[@]}#方法2
    apple pear

    3.使用别名

    amosli@amosli-pc:~/learn$ alias install='sudo apt-get install' #为sudo apt-get install设置别名install

    这个关闭当前终端即会失效。

    amosli@amosli-pc:~/learn$ echo 'alias cmd="command seq"' >> ~/.bashrc #定义全局变量
    amosli@amosli-pc:~/learn$ vi /home/amosli/.bashrc #使用vi删除刚才设置的别名

    4.获取终端信息

    使用tput和stty两款工具

    获取终端的行数和列数

    amosli@amosli-pc:~/learn$ tput cols
    80
    amosli@amosli-pc:~/learn$ tput lines
    24

    打印终端的名称:

    amosli@amosli-pc:~/learn$ tput longname
    X11 terminal emulatoramosli@amosli-pc:~/learn$ 
    amosli@amosli-pc:~/learn$ tput setb no #更改背景色no可以取值为0-7
    amosli@amosli-pc:~/learn$tput setb bold #字体加粗

    5.获取、设置日期和延时

    amosli@amosli-pc:~/learn$ date
    2013年 12月 19日 星期四 00:13:01 CST

    打印纪元时,纪元时被定义为从1970年1月1日0时0分0秒起至当前时刻的总秒数,不包括闰秒

    amosli@amosli-pc:~/learn$ date +%s
    1387383256

    按格式输出:

    amosli@amosli-pc:~$ date "+%d %b %Y"
    19 12月 2013
    amosli@amosli-pc:~$ date "+%d %B %Y"
    19 十二月 2013
    格式列表如下:
    星期
    %a Sat %A Saturday %b Nov %B November %d 19 固定日期格式mm/dd/yy %D   12/19/13 %y 13 %Y 2013 小时 %I/%H 00 分钟 %M 41 %S 10 纳秒 %N 696308515 Unix纪元时 %s

    延时

    sleep number_of_seconds

     6.调试脚本

    打印出所执行的每一行命令

    bash -x script.sh
    sh -x script.sh

    可以在脚本使用set built-in 来启用或禁止调试打印

    set -x:在执行时显示参数和命令

    set +x:禁止调试

    set -v:当命令进行读取时显示输入

    set +v:禁止打印输入

    实例:

    #debug.sh
    for i in {1..6}
    do
    set -x
    echo $i
    set +x
    done
    echo "Script executed"
    
    
    amosli@amosli-pc:~/learn$ sh -x debug.sh 
    + set -x
    + echo {1..6}
    {1..6}
    + set +x
    Script executed

    直接修改脚本

    #!/bin/bash -xv

    7.函数和参数

    定义函数

    function fname()
    {
        statements;
    }
    or
    fname()
    {
        statements;
    }

    函数调用

    fname;
    fname arg1 arg2;#传递参数

    示例:

    amosli@amosli-pc:~/learn$ fname(){
    > echo $1,$2;#访问参数1和参数2
    > echo "$@";#以列表的方式一次性打印所有参数
    > echo "$*";#类似于$@,但是参数被作为单个实体
    > return 0;#返回值
    > }
    amosli@amosli-pc:~/learn$ fname 3 4;
    3,4
    3 4
    3 4
    说明:
    $
    1第一个参数 $2第二个参数 $nn个参数 "$@"被扩展成 "$1" "$2" "$3" "$*"扩展成"$1c$2c$3", 其中cIFS第一个字符 "$@"使用最多, $*将所有的参数当做单个字符串

    bash支持递归 ,可以了解一下Fork炸弹' :(){ :|:& };: '

    导出函数,可以作用到子进程中

    export -f fname

    函数及命令返回值

    cmd;
    echo $?#读取命令返回值
    退出状态,成功退出,状态为0,否则,非0

    8.读取命令序列输出(管道 pipe)

    一个命令的输出可以作为另一个命令的输入,而这个命令的输出又会传递到另一个命令,依此类推,即是管道的思想。

    $cmd1 | cmd2 | cmd3

    实例:

    amosli@amosli-pc:~/learn$ ls | cat -n > out.txt
    amosli@amosli-pc:~/learn$ cat out.txt 
         1    a1
         2    a2
         3    a3
         4    debug.sh
         5    input.txt
         6    output.txt
         7    out.txt
         8    sleep.sh
         9    stderr.txt
        10    stdout.txt
        11    test1.txt
        12    uid.sh
        13    variables.sh

    ls 的输出(当前目录内容的列表)被传递给cat -n ,cat -n 为通过stdin所接收到输入内容加上行号,然后将输出重定向到文件out.txt

    读取命令输出

    cmd_output=$(COMMANDS) #subshell 子shell
    or
    cmd_output=`COMMANDS`#back-quote反引用

    保留空格和换行符

    amosli@amosli-pc:~/learn$ cat -n> text.txt
    amosli@amosli-pc:~/learn$ cat text.txt 
         1    
         2    
         3    
         4    
    amosli@amosli-pc:~/learn$ out=$(cat text.txt)
    
    amosli@amosli-pc:~/learn$ echo $out
    1 2 3 4
    amosli@amosli-pc:~/learn$ out2="$(cat text.txt)" #这里依然丢失了,不知道为什么,应该会保留的。
    amosli@amosli-pc:~/learn$ echo $out2
    1 2 3 4
    out=$(cat text.txt)
    echo $out  #丢失所有换行符
    
    out="$(cat text.txt)"
    echo $out  #保留

     

  • 相关阅读:
    NoSQL数据库 Couchbase Server
    百度推广账户搭建思路
    禅道发邮件配置
    ASP 500错误解决方法
    MYSQL无法连接,提示10055错误尝试解决
    制作不随浏览器滚动的DIV-带关闭按钮
    [CSS3] :nth-child的用法
    [JS] 四角度旋转特效
    [JS] 瀑布流加载
    [CSS3] 二级下拉导航
  • 原文地址:https://www.cnblogs.com/amosli/p/3481331.html
Copyright © 2011-2022 走看看