zoukankan      html  css  js  c++  java
  • shell知识点

    各个项目以实践为主。原理及更多细节介绍,请查看官方文档:

    例如:bash,grub,postfix,pam,fastcgi,httpd,rsync等诸多项目。

    各种总结表格

    http://www.cnblogs.com/xkfz007/archive/2012/02/02/2336318.html

    http://blog.sina.com.cn/s/blog_6bd7d943010151a1.html

    Linux下产生随机密码的10方法 

    shell 彩色化更改

    /etc/DIR_COLORS,具体看文件,一看就懂了

    A,dircolors -p > ~/.dircolors
    B,cp /etc/DIR_COLORS ~/.dircolors

    http://www.linuxsir.org/bbs/thread112305.html   控制台彩色更改

    fbterm,setterm,xterm

    传递参数

    通过脚本里的变量传递参数

    通过命令行传递参数

    通过固定的一个文件传递参数

    cat -A显示所有不可见字符

    [root@250-shiyan sh]# cat -A mylsfile
    check-root.sh$
    efii^I^Ith.sh$
    for.sh$
    ser.sh$

    脚本的本质

    只关心输入与输出,在一个脚本中,看有几个输出,每个输出是否有响应(输入),便可以很好的理解脚本的作用

    界面与编辑器

    行编辑器,vi 屏幕编辑器,sed 文本流编辑器

    cli 命令行界面,tui 类似于setup或编译内核时的界面,gui 图形界面

    脚本文件与可执行文件(二进制文件)
    [root@localhost bin]# file /sbin/* |grep script
    [root@localhost bin]# file /bin/* |grep script
    [root@localhost bin]# file /usr/sbin/* |grep script
    [root@localhost bin]# file /usr/bin/* |grep script
    只有以下四种脚本类型
    c99:                     POSIX shell script text executable
    ldd:                     Bourne-Again shell script text executable
    pydoc:                   a /usr/bin/python2.6 script text executable
    urlgrabber:              a /usr/bin/python -t script text executable
    yum:                     a /usr/bin/python script text executable

    两种学习方式
    你想学习shell脚本编程,这很不错。于是你拿了一本书开始学习。一些人会首先通读整本教材后再上机练习。这种方法可能适用于一些人,但我却不太看好它。
    我的建议是,仅仅学一些最基础的能够让你开始编码的知识就可以了。之后,动手写一些简单的程序吧。一旦你由于知识上的欠缺而不得不停止时,再回到书本上去读你想要了解的那部分,
    然后继续做你的项目。如此周而复始,不断提高你的水平。这种边学边做的方法曾让我受益良多。

    三种脚本执行方式(4种)
    1 source bash_profile   . bash_profile两者等效   不需要执行权限
    2 bash bash_profile   不需要执行权限
    3 ./filename          需要执行权限

    一般的脚本文件是新产生一个子shell,然后在其下执行命令,一般是在脚本文件前加入#!/bin/bash这一行
    实验证明写脚本时加不加#!/bin/bash这一行没有关系。
    source命令即点命令,在当前进程中执行脚本文件中的各个命令,不产生新的shell(sub-shell)
    source从c-shell而来,点命令从bourne-shell而来,二者等效。
    当前脚本中设置的变量也将作为脚本的环境,source和点通常用于重新执行刚修改的初始化文件,如.bash_profile等

    source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

    bash scriptfiles        不需要执行权限 产生子shell。
    source scriptfiles        不需要执行权限 不产生子shell,在本shell中执行的。
    . scriptfiles            不需要执行权限 不产生子shell,在本shell中执行的。
    scriptfiles            scriptfiles需要执行权限,还需要将此文件放入PATH中才可以,否则要使用绝对路径。是在子shell中运行的,结果不影响父shell
    脚本文件与source和点的区别
    脚本文件启动子shell来执行命令,这样如果把设置环境变量的命令写入脚本中,就只会影响子shell,无法改变当前shell,所以通过文件设置变量时,要用source命令。

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

    举例说明:
    1.新建一个test.sh脚本,内容为:A=1
    2.运行sh test.sh后,echo $A,显示为空,因为A=1并未传回给当前shell
    3.或者chmod 777 test.sh,并且cp test.sh /bin/这样便可以在搜索路径中找到,直接执行了
    4.运行test.sh后,也是一样的效果
    5.运行source test.sh 或者 . test.sh,然后echo $A,则会显示1,说明A=1的变量在当前shell中

    [root@250-shiyan sh]# cat pstr  可以一边观察进程的产生,一边执行脚本
    #!/bin/bash
    while sleep 2
     do
     pstree
     done

    [root@109-com1 asterisk]# while sleep 2; do pstree;done

    [root@109-com1 ~]# while sleep 1;do echo `/usr/sbin/ss -n|grep ESTAB|awk '($2 && $3)!~/0/{printf $0}'`;done

    七种文件类型
    shell中的常规文件是指-rwxrwxrwx,有减号就是
    #stat 文件名 便可以看出 有regular file标志的就是
    文件类型对应于上面的st_mode, 文件类型有很多,比如常规文件、符号链接(硬链接、软链接)、管道文件、设备文件(符号设备、块设备)、socket文件等,不同的文件类型对应不同的功能和作用。
    -常规文件,d目录,l符号链接,b块设备,c字符设备,s套接字,p管道

    每一种文件都可以用相应的命令创建,如

    touch a 创建常规文件

    mkdir a 创建目录

    ln -s a 创建链接

    mkfifo 创建命名管道

    MAKEDEV 创建设备文件 包含在包MAKEDEV中

    mksock 创建套接字文件 包含在包MAKEDEV中

    管道分为有名管道与无名管道

    无名就是在当前shell中类似grep root /etc/passwd | wc -l这种方式

    有名可以在两个终端之间协同工作,例如在一个终端mkfifo aa;ifconfig > aa。在另一个终端接收管道传过来的流,即tail -f aa

    shell通配符  ? ,*, {strings1,strings2,...}, [list], [!list], [^list], [c1-c2]

    shell元字符

    shell转义符  

    shell各种符号用法


    四个引用符号  " ' `

    为防止shell解释一些东西,所以就有了引用,四种符号 " ' `
    双引、单引和反引号
    使用反斜线实现屏蔽,转义。反斜线引用单个字符时,称它为转义字符
    双引号除$ ` 三种符号外,引用所有内容,称为弱引用
    [root@localhost script]# echo "$TERM pwd "
    xterm pwd
    [root@localhost script]# echo "`ls` pwd "
    passwd
    user pwd
    [root@localhost script]# echo "\`ls\` pwd "
    `ls` pwd
    单引号引用所有内容,没有字符拥有特殊含义,称为强引用
    反引号
    shell试图替代单词hello为系统命令并执行它,因为hello脚本或命令不存在,返回错误信息。
    [root@localhost script]# echo `hello`
    -bash: hello: command not found
    [root@localhost script]# echo `date`
    Mon Dec 30 18:08:21 CST 2013

    [root@250-shiyan sh]# echo "who "fi""
    who fi
    [root@250-shiyan sh]# echo "who "fi""
    who "fi"

    命令替换看后两例子

    命令替换两种形式

    $(command)或`command`

        filelist=`ls -al`  
        echo $filelist  
          
        # put contents of the file into a varible  
        filecontent=`cat export.txt`  
        echo $filecontent  
          
        # produce a varible from a loop  
        var1=`for i in 1 2 3 4 5  
            do  
                echo -n $i # this echo is very important  
            done`  
        echo $var1  
          
        i=0  
        var2=`while [ $i -le 10 ]  
            do  
                echo -n $i #this echo is very important  
                i=$((i+1))  
            done`  
        echo $var2  
          
        word_count=$( wc -w $(ls -l | awk '{print $9}') )  
        echo $word_count  
          
        word_count=`wc -w \`ls -l | awk '{print $9}'\``  # 反引号也可以嵌套替换,但是需要通过进行转意  
        echo $word_count  


    四个shell命令执行顺序符号 &&,||,(),{}

    &&运算符:
    command1  && command2
    &&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;换句话说,“如果这个命令执行成功&&那么执行这个命令”。
    (cmd1;cmd2;...;cmdN)      # 在一个子shell里执行一组命令
    {cmd1;cmd2;...;cmdN}     #  在当前shell里执行一组命令

    ||运算符:
    command1 || command2
    ||则与&&相反。如果||左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2);或者换句话说,“如果这个命令执行失败了||那么就执行这个命令。

    ()运算符:
    为了在子shell中执行一组命令,可以用命令分隔符(即",")隔开每一个命令,并把所有的命令用圆括号()括起来。

    {}运算符:
    如果使用{}来代替(),那么相应的命令将在当前shell中作为一个整体被执行。

    $ A=1;echo $A;{ A=2; };echo $A
    1
    2
    $ A=1;echo $A;( A=2; );echo $A
    1
    1
    { A=2; }改变了当前shell变量的值
    ( A=2; )未改变当前shell变量的值

    四种变量类型
    环境变量(也叫shell变量)  是一类Shell预定义变量。环境变量由系统统一命名,全部大写。部分系统变量的值由系统设定,部分环境变量的值可以由用户给定。由export关键字处理过的变量叫做环境变量。因为通常情况下仅仅在登录脚本中使用环境变量。
    位置变量(也叫shell参数)  函数,脚本等都需要参数,就是用来获得这些参数的。相当于其它编程语言的形参
    $0 $1 $2 $3 $4 $5 $6 $7 $8 $9
    特殊变量(预定义变量)  $! $* $# $? $$ $@
    自定义变量

    五种变量赋值方法:使用read命令,直接赋值,使用命令行参数,使用命令行的输出结果,从文件读取。

    变量括号
    变量名=值
    取出变量值可以加一个美元符号($)在变量前面
    变量名不可以直接和其他字符相连,如果想相连,必须用括号:
    #num=2
    #echo “this is $(num)nd!”

    env与set的区别

    env用于显示用户环境区中的变量及其取值;set用于显示本地数据区和用户环境区中的变量及其取值;unset用于删除指定变量当前的取值,该值将被指定为NULL;export命令用于将本地数据区中的变量转移到用户环境区。
    新的变量会在本地数据区分配内存进行存储,这个变量归当前的Shell所有,任何子进 程都不能访问本地变量。这些变量与环境变量不同,环境变量被存储在另一内存区,叫做用户环境区,这块内存中的变量可以被子进程访问
    env(查看全局环境变量)
    set(显示为某个特定进程设置的所有环境变量,包括全局变量,剩下的为局部变量)

    登录shell 优先级在tty与pts中是不一样的   http://blog.csdn.net/zlm_250/article/details/7949415
    1./etc/profile
    2./etc/profile.d/*.sh
    3.$HOME/.bash_profile
    4.$HOME/.bash_login 如果有的话
    5.$HOME/.profile 如果有的话
    6.$HOME/.bashrc
    7./etc/bashrc
    8.$HOME/.bash_logout
    tty中的顺序是 1-2-3-5-6-7-8
    pts中的顺序是 1-3-5
    会从4个不同的启动文件里读取命令,顺序依次为:/etc/profile -> /etc/profile.d/*.sh -> (~/.bash_profile | ~/.bash_login | ~/.profile) -> ~/.bashrc -> /etc/bashrc -> ~/.bash_logout
    $HOME/.profile中会检查系统上有没有$HOME/.bashrc文件,如果有则执行

    (1) /etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置。
    (2) /etc/bashrc: 为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取(即每次新开一个终端,都会执行bashrc)。
    (3) ~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次。默认情况下,设置一些环境变量,执行用户的.bashrc文件。
    ~/.bash_profile: 是交互式、login 方式进入 bash 运行的~/.bashrc 是交互式 non-login 方式进入 bash 运行的通常二者设置大致相同,所以通常前者会调用后者。
    (4) ~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。
    (5) ~/.bash_logout: 当每次退出系统(退出bash shell)时,执行该文件. 另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承 /etc/profile中的变量,他们是"父子"关系。

    在以上文件之中第二行分别写上一句echo “”(用以区分不同的文件),然后退出当前shell,重新登录,便可看出执行顺序。

    RETVAL=$?  是将前面的执行结果赋给retval
    没有规定在设置变量时一定要用双引号,但在进行字符串比较时必须这样做
    当使用字符时,应总是使用双引号,无论它是单个字符串或是多个单词。

    对当前路径的处理——$PWD, 但此值随cd指令而变,因此建议保存在另一个变量中
    #!/bin/bash
    a="$PWD"
    echo $a
    ls $a

    command line

    command options arguments

    options ,执行任务的方式,控制命令的动作,选项也称开关switches或者标志flags
    arguments ,指定命令使用的数据
    空白符,使用空格和制表符作为分隔符的思想,是如此的重要,所以他们有自己的名称,空白符
    space,制表符,新行字符(Carriage Return回车符)
    [root@localhost script]# set |grep IFS
    IFS=$' '
    newline 新行字符
    return 回车符
    tab 制表符

    使用者每输入一个键,cursor 就往后移动一格,直到碰到命令行读进 CR(Carriage Return,由 Enter 键产生)字符为止
    所谓的命令行,就是在 shell prompt 与 CR 字符之间所输入的文字。
    若从技术细节来看,shell 会依据 IFS(Internal Field Seperator) 将 command line 所输入的文字给拆解为"字段"(word)。
    然后再针对特殊字符(meta)先作处理,最后再重组整行 command line 。
    其中的 IFS 是 shell 预设使用的字段分隔符,可以由一个及多个如下按键组成:
    * 空格键(White Space)
    * 制表键(Tab)
    * 回车键(Enter)
    系统可接受的命令名称(command-name)可以从如下途径获得:
    * 明确路径所指定的外部命令
    * 命令别名(alias)
    * 自定功能(function)
    * shell 内建命令(built-in)
    * $PATH 之下的外部命令
    每一个命令行均必需含有命令名称,这是不能缺少的。

    简单而言(我不敢说这是精确的定义,注一),command line 的每一个字符,分为如下两种:
    * literal:也就是普通字符,对 shell 来说没特殊功能。
    * meta:对 shell 来说,具有特定功能的特殊保留字符。
    IFS space,tab,enter
    CR carriage return
    = $ >等
    IFS 是用来拆解 command line 的每一个词(word)用的,因为 shell command line 是按词来处理的。
    而 CR 则是用来结束 command line 用的。

    命令名 选项 参数  
    getconf -a   |grep "PAGE"
    tune2fs -l /dev/sda1 |grep "Block"
    readelf -a /usr/bin/tee  
    pmap -x 16441  
    size   /usr/bin/tee  
    tar zxvf *.tar.gz  
    blockdev --report    
    fdisk -l    
    stat   /boot  
    sar -n DEV 1  
    du -sh /var/log  
    df -h   |column -t
    命令名 正则 通配
    ls   *
    grep * *
    find *  
    sed *  
    awk *  

    bash -v引起的问题

    另外在测试source运行脚本时,有些误操作,导致在执行命令时,都会首先输出一下当前运行命令。
    如下所示:
    [u1@localhost performance]$ cd tools/
    cd tools/
    [u1@localhost tools]$ cd ..
    cd ..
    [u1@localhost performance]$
    看起来实在是有点多余,作为一个有轻微洁癖的人,当然想办法要消除它。不过一时竟不知如何下手,而且这个现象也不好描述,就算想google也不行呀。
    不过我看到另外打开的一个section是没有这个问题的,因此想到对比两个section的env。
    一对比还真发现有些不同,SHLVL这个变量正常的section为1,会首先输出执行命令的section为3。
    所以怀疑到是在section运行了bash的原因,在会首先输出执行命令section里面连续输入两次exit之后,现象消失了。
    再次在该section里面输入bash,并没有重现之前的现象。
    运行bash –help看了一下,怀疑是bash –v/—verbose的原因。再次尝试输入bash -v,现象重现。
    前后花了不少时间,藉此记录一下~

    服务列表

    有后台进程 只有内核模块,无后台进程
    sshd lvs
    httpd iptables
    crond  
    vnc  
    nfsd  
    udevd  
    rsyslogd  
    auditd  
       
  • 相关阅读:
    creat-react-app/dva静态项目,用nginx部署在次级域名路径(如a.com/sub/)需要注意的几点
    如何在 Rails 中搭配 Turbolinks 使用 Vue
    绝对干货!漫谈美团APP对Crash的治理之路
    下载更省心!12月这些应用获得了绿色应用认证!
    代码之外的生存指南,这6本书助你提升软实力
    “社交通讯类”Target SDK≥26优秀应用展示
    “实用工具类”Target SDK≥26优秀应用展示
    “购物比价类”Target SDK≥26优秀应用展示
    知否知否!应用市场上架Target SDK新规来袭
    大咖推荐!今年值得一读的6本技术类书籍
  • 原文地址:https://www.cnblogs.com/createyuan/p/3794649.html
Copyright © 2011-2022 走看看