zoukankan      html  css  js  c++  java
  • shell

    shell 脚本的第一行一般为:

    #! /bin/sh

    ll /bin/sh 可以发现 sh 是一个指向 bash 的软连接。脚本文件一般有两种运行方式,一种是作为 sh 命令的命令行参数,另一种是将脚本作为具有可执行权限的可执行文件,对于后一种方式来说,上面的那句话就有作用了,它指定了调用哪种解释器来运行脚本。

    date:用于显示和设置时间

    #输出时间:
    date        #以本地时间格式输出当前时间
    date +%s    #以时间戳形式输出当前时间
    
    #本地时间格式与时间戳转换:
    date +%s -d "2013/9/23 10:40:00"    #将指定时间转换成时间戳>格式
    date -d @1379895103     #指定时间戳转换成本地时间格式
    
    #设置时间:
    date -s 2013/9/23     # date -s 2013-9-23
    date -s 10:30:00
    date -s "2013/9/23 10:30:00"

    time:计算某一任务运行的时间。通过 type -a time 查看,可以发现 linux 中有两个 time,还有一个是 /usr/bin/time ,没有可安装,它显示的信息比下面会更多一些,包括一些CPU占用和IO等情况,使用方法如 /usr/bin/time -v make -j4,此处略过。

    # TIMEFORMAT 环境变量用来自定义输出的时间格式
    export TIMEFORMAT=$'real %2R
    user %2U
    sys %2S'    # 有 -p 参数的时间格式
    time date
    export TIMEFORMAT=$'real %2R
    ' # 只输出 real 时间
    time date
    export TIMEFORMAT=$'
    real	%3lR
    user	%3lU
    sys	%3lS'    #默认时间格式
    time date
    time -p date    # -p 参数可以指定以 POSIX 缺省时间格式打印结果,单位为秒

    who: show who is logged on

    who -aH     #输出系统上次引导时间、当前运行级别和当前登陆用户,及其它用户登陆信息,-H 表示显示表头(即标题)
    who -b      # -b: boot 上次引导时间
    who -r      # -r: run 当前运行级别,同 runlevel
    who -u      # -u: user 当前登录用户
    whoami      # 只输出当前登录用户的用户名

    wc  计算机文件中的行数、单词数和字符数

    wc -l /etc/passwd   # -l: line 行数
    wc -w /etc/passwd   # -w: word 行数
    wc -c /etc/passwd   # -c: char 行数
    wc -l ~/code/src/*.cpp  # 依次输出 ~/code/src/*.cpp 的行数与总量
    ls -l *.cpp | wc -l # 查看当前目录有多少个 *.cpp 文件

    cp 复制命令

    cp -u   # -u: update 当源文件比目标文件新的时候,才复制
    cp -p   # -p: preserve 保持源文件的属性:模式,所有权,时间戳
    cp -s   # -s: symbolic-link 软连接,同 ln -s ,ln 默认为硬连接

    注:硬连接(Hard Link):硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

    软连接(Symbolic Link):软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

    mkdir 创建目录

    mkdir -pv -m=rwx test/test
    # -p: parents 两个作用:1、可以创建需要的多级目录。2、即使目录存在,也不报错
    # -v: verbose 创建详情,如果创建成功则输出信息
    # -m: mode 创建时赋予权限,同 chmod

    不同文件的特殊字符标识:可以通过 ls 命令查看,也可以通过 file 命令。

    -       # 普通文件,如文本文件,二进制文件等
    d       # 目录
    l       # 符号连接文件(软连接)
    c       # 字符特殊文件,提供对设备不带缓冲的访问,每次访问长度可变。
    b       # 块特殊文件,提供对设备带缓冲的访问,每次访问以固定长度为单位进行。
    p       # 命名管道,用于进程间通信(IPC)
    s       # sockek,用于进程间网络通信

    chmod 修改权限

    chmod 777 src               # 777 分别设置 usergroupother 三者(all)权限,八进制方式,1表示执行,2表示写,4表示读,相加得复合权限,八进制方式只能设置权限,而不能增加或去除权限
    chmod a-x src               # =/+/- rwx 用于赋予或增加或去除权限,a 表示 all,也可为 u,g,o ,也可写成 ugo-x,默认不写为 a
    chmod u+rwx,g+x,o=rw src    # 同上,可以在一起分别设置
    chmod a+x -R src            # 递归修改目录权限
    chmod a+x -v src            # 输出修改成功后的权限信息

    chown 和 chgrp : 修改所有者和所有组

    chown -v -R root filename           # 修改所有者 -R 表示递归修改,-v 输出修改结果
    chown -v root:root filename         # 修改所有者和所有组
    chown -v :root filename             # 只修改所有组,同 chgrp
    chgrp -v root filename              # 同上

    后台进程:

    可以在执行命令时,在命令后面加上 & 符号,使其在后台运行。如 make & ,但作业在后台运行一样会将结果输出到屏幕上,干扰工作。可以通过如下方式,把输出重定向到文件:

    make -j8 > result 2>&1 &

    make -j8 1> /dev/null &     #将标准输出扔掉,将错误输出仍默认输出到终端

    另外,对于正在运行的作业,也可以通过 Ctrl+Z 键盘挂起作业,然后通过 bg %jobnumber 来令其在后台运行(相应的,可以使用 fg %jobnumber 令其在前台运行),并可以通过 jobs 命令查看当前挂起和在后台运行的作业。,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

    当关闭 shell 窗口时,由于父进程是当前终端 shell 的进程,而一旦父进程退出,则会发送 hangup 信号给所有子进程,子进程收到 hangup 以后也会退出。如果我们要在退出 shell 的时候继续运行进程,则需要使用 nohup 忽略 hangup 信号,或者 setsid 将将父进程设为 init 进程。

    但是最好的方式,还是使用 screen  

    关于后台进程,参见 http://blog.sina.com.cn/s/blog_3e3be35e0100oi9i.html

    有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不

    再启用其他shell。

      新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

      #!/bin/sh

      一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

      另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

    exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的

    进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

    exec与system的区别

      (1) exec是直接用新的进程去代替原来的程序运行,运行完毕之后不回到原先的程序中去。

      (2) system是调用shell执行你的命令,system=fork+exec+waitpid,执行完毕之后,回到原先的程序中去。继续执行下面的部分。

    总之,如果你用exec调用,首先应该fork一个新的进程,然后exec. 而system不需要你fork新进程,已经封装好了。

    详见:http://blog.csdn.net/cyberrusher/article/details/7253385

    source filename 与 sh filename 及./filename执行脚本的区别在那里呢?source命令也称为"点命令",也就是一个点符号。

    1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。
    2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
    3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

    echo 和 printf

    echo 默认结尾带换行符(可以通过 -n 参数取消),而 printf 默认结尾不带换行符。

    #!/bin/bash
    echo Hello,World!       # 不能输出分号,因为分号是命令界定符
    echo 'Hello,World!'     # 不能输出变量值,如 $PATH,只会原形即"$PATH"
    echo "Hello,World"      # 不能输出  等特殊符号,不过可以使用 set +H 之后改变这一情>况
    set +H
    echo "Hello,World!"
    echo "$PATH"
    echo "newline
    
    "      # 仍然是不完美的,会直接输出 
    
     字符,需要加 -e 参数才能识
    别转义字符
    echo -e "e[1;31mThis is red texte[0m"
    
    # 一般 echo 只用于最简单的输出,对于稍微复杂点的输出,请使用 printf
    printf "$PATH
    Hello,World!
    "
    printf "%s
    %s
    " $PATH Hello,World

    管道符 program1|program2

    表示将前者的标准输出重置为后者的标准输入。 < 和 > 和 >> 也可将输入与输出连接到文件,管道却可以把两个执行中的程序衔接到一起

    模拟登录脚本:

    read -p "login as:" login
    printf "$login@"
    ifconfig eth0 | sed -n "2,2p" | awk '{printf substr($2,6)}'
    printf "'s password:"
    stty -echo
    read password < /dev/tty
    printf '
    '
    stty echo

    pgrep 和 pkill

    #!/bin/bash
    pgrep -l -u root sshd       # -l: list 显示进程名,-u 指定进程所属用户,可以简写成 pgrep -luroot sshd
    pkill -9 -u root yychat     # 等同于 pgrep -uroot yychat | xargs kill -9

    pmap : 查看进程的内存映像信息

    [root@localhost ~]# while true; do pmap -d  27841 | tail -1; sleep 2; done
    mapped: 502368K    writeable/private: 64024K    shared: 0K
    mapped: 502368K    writeable/private: 64024K    shared: 0K
    mapped: 502368K    writeable/private: 64024K    shared: 0K
    
    # mapped 表示该进程映射的虚拟地址空间大小,也就是该进程预先分配的虚拟内存大小,即ps出的vsz
    # writeable/private 表示进程所占用的私有地址空间大小,也就是该进程实际使用的内存大小      
    # shared 表示进程和其他进程共享的内存大小

    read: 从键盘上读取

    read var                    # 从键盘读取字符串放入 var
    read -p "login as:" var     # -p: 提示信息
    read -s "password:" var     # -s: 不回显
    read -n 2 var               # -n: 读取 n 个字符
    read -t 3 var               # -t: 特定时限(秒)
    read -d ":" var             # -d: 使用定界符结束输入

     IFS: 内部字段分隔符(Internal Field Separator)

    data="a,b,c"
    oldIFS=$IFS      
    IFS=,               # IFS默认值是空白字符(换行符、制表符或空格)
    for item in $data
    do
        echo Item:$item
    done;
    IFS=$oldIFS

    if 语句

    read -p "Enter x:" x
    read -p "Enter y:" y
    if [ $x > $y ]      # 注意 [ ] 与之间的表达式必须要有空格
    then
        echo "$x>$y"
    elif [ $x -lt $y ]
    then
        echo "$x<$y"
    else
        echo "$x==$y"
    fi
    
    # -eq: ==       # equal             也可以写成 = ,但注意,= 两边必须有空格,如果没有空格,就是赋值
    # -ne: !=       # not equal
    # -gt: >        # greater than
    # -lt: <        # less than
    # -ge: >=
    # -le: <=
    
    # 简单条件语句的写法:
    # [ condition ] && action       # 如果 condition 为真,则执行后面语句
    # [ condition ] || action       # 如果 condition 为假,则执行后面语句
    # 此外,逻辑与/逻辑或 也可以写成:
    # [ condition1 -a condition2 ]  # 逻辑与,或 [ condition1 ] -a [ condition2 ]
    # [ condition1 -o condition2 ]  # 逻辑或,或 [ condition1 ] -o [ condition2 ]
    
    # 文件系统相关测试:
    # [ -f $file_var ]: 如果给定变量包含正常文件路径或文件名,则返回真
    # [ -x $file_var ]: 如果给定变量包含的文件可执行,则返回真
    # [ -d $file_var ]: 如果给定变量包含的是目录,则返回值,注:如果这里是 -c/-b/-L,则分别对应字符设备文件、块设备文件、符号链接
    # [ -e $file_var ]: 如果给定变量包含的文件存在,则返回值
    # [ -r $file_var ]: 如果给定变量包含的文件可读,则返回真,注:如果这里是 -w 表示可写
    fpath="/etc/passwd"
    if [ -e $fpath ];then
        echo "File exits";
    else
        echo "Don't exits";
    fi
    
    # -eq: ==       # equal             也可以写成 = ,但注意,= 两边必须有空格,如果没有空格,就是赋值
    # -ne: !=       # not equal
    # -gt: >        # greater than
    # -lt: <        # less than
    # -ge: >=
    # -le: <=
    
    # 简单条件语句的写法:
    # [ condition ] && action       # 如果 condition 为真,则执行后面语句
    # [ condition ] || action       # 如果 condition 为假,则执行后面语句
    # 此外,逻辑与/逻辑或 也可以写成:
    # [ condition1 -a condition2 ]  # 逻辑与,或 [ condition1 ] -a [ condition2 ]
    # [ condition1 -o condition2 ]  # 逻辑或,或 [ condition1 ] -o [ condition2 ]
    
    # 文件系统相关测试:
    # [ -f $file_var ]: 如果给定变量包含正常文件路径或文件名,则返回真
    # [ -x $file_var ]: 如果给定变量包含的文件可执行,则返回真
    # [ -d $file_var ]: 如果给定变量包含的是目录,则返回值,注:如果这里是 -c/-b/-L,则分别对应字符设备文件、块设备文件、符号链接
    # [ -e $file_var ]: 如果给定变量包含的文件存在,则返回值
    # [ -r $file_var ]: 如果给定变量包含的文件可读,则返回真,注:如果这里是 -w 表示可写
    fpath="/etc/passwd"
    if [ -e $fpath ];then
        echo "File exits";
    else
        echo "Don't exits";
    fi
    
    # 字符串比较时,最好使用 [[ 和 ]] ,有时采用单中括号可能会有问题
    # [[ -n $str ]]: 如果 str 包含的是非空字符串,则返回真
    # [[ -z $str ]]: 如果 str 包含的是空字符串,则返回真
    
    # test 用来执行条件检测,有助于过多使用中括号。
    if test 3 -gt 1; then
        echo "3>1";
    fi

    复合命令:不同命令间用分号隔离,这样会依次执行。

    普通用户帐号使用$作为提示符,root帐号使用 # 作为提示符。

    shell 登录过程:

    1、执行 /etc/profile,同时该文件内会遍历执行 /etc/profile.d/ 下的 *.sh 配置文件。

    2、执行 .bash_profile (或 ~/.bash_login 或 ~/.profile),同时该文件内会执行  ~/.bashrc,而该文件内又会调用 /etc/bashrc

    3、在退出 shell 时,会执行 ~/.bash_logout

    man 有 8 个不同的指南组成:(我感觉下面说得太乱,需要重新找下资料)

    1、命令

    2、UNIX 系统调用

    3、库,用来存储由 C 程序员使用的与内核无关的函数

    4、文件格式,如 /etc/passwd 等文件的格式

    5、同样是文件格式

    6、包括了玩UNIX所带游戏的指令

    7、设备驱动程序

    8、系统维护

  • 相关阅读:
    C# NPOI 导入与导出Excel文档 兼容xlsx, xls(xf13中已经引用了xlsx的npoi)
    ASP.Net超时时间已到解决办法-
    解决SqlDataSource连接超时的问题
    SqlDataSource控件超时的困惑
    Redis+Keepalived
    Linux Ubuntu 16.04 安装步骤+远程环境
    JDK 安装
    Maven 安装
    CAT 默认密码修改
    CAT 监控搭建
  • 原文地址:https://www.cnblogs.com/tianyajuanke/p/3334485.html
Copyright © 2011-2022 走看看