zoukankan      html  css  js  c++  java
  • BASH 环境

    本节内容

    1.  什么是shell

    2.  命令的优先级

    3.  元字符

    4.  登录shell与非登录shell 

    一  什么是shell

    shell一般代表两个层面的意思,一个是命令解释器,如bash;另外一个就是shell脚本

    命令解释器shell的发展历史 sh -> csh -> ksh -> tcsh -> bash,重点学习bash

    二  命令的优先级
    ==> alias
        ==> Compound Commands
            ==> function
               ==> builtin
                   ==> hash
                       ==> $PATH
                           ==> error:command not found

    获取一个命令会按照上述优先级去寻找,先找同名的alias,再早compound命令......

    ==========================part1======================================

    让我们从最简单的入手:别名、内部命令、外部命令,来探讨它们三者的优先级

    别名:别名命令是为了简化输出给一个长参数命令的整合,别名的定义方法:alias la="ls -al" 取消别名 unalias la

    内部命令:是bash自带的命令,功能简单, man builtin

    外部命令:小程序存在 /bin/  /sbin/  /usr/bin/等地方

     

    [root@localhost ~]# alias cd
    -bash: alias: cd: not found

    cd是一个内部命令,属于bash自带命令(man cd) 它没有定义别名

    [root@localhost ~]# alias ls
    alias ls='ls --color=auto'

    ls定义了别名

    [root@localhost ~]# which ls
    alias ls='ls --color=auto'
               /usr/bin/ls

    ls 实际是一个外部命令,属于可执行程序 通过C代码编译得出的可执行程序

    [root@localhost ~]# file /usr/bin/ls
    /usr/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=3d705971a4c4544545cb78fd890d27bf792af6d4, stripped

     

    测试优先级原理:别名、内部命令、$PATH中设置相同的命令名,测试哪个命令先执行

    [root@localhost ~]# alias cd='ls -l'   # 建立一个别名cd实际指向 /usr/bin/ls

    [root@localhost ~]# cp /bin/hostname /usr/local/sbin/cd  # 在PATH第一个目录放入一个cd命令

     

    [root@localhost ~]# cd
    total 8
    -rw-------. 1 root root 1791 Sep 21 11:00 anaconda-ks.cfg
    -rw-r--r--. 1 root root 1819 Sep 21 03:10 initial-setup-ks.cfg

    [root@localhost ~]# unalias cd    删除别名 

    [root@localhost ~]# cd    执行真正的内部命令
    [root@localhost ~]#

    [root@localhost ~]# /usr/local/sbin/cd
    localhost.localdomain
    [root@localhost ~]#

    [root@localhost ~]# rm -rf /usr/local/sbin/cd

     

    小结一:命令的执行顺序

    别名(alias 查看别名)   >  bash 内部命令 > $PATH 中按冒号分割的每个路径中去搜索

     

     ps: 登录后的预置别名从何而来(应该学会:建立别名和取消别名,固话别名配置无非将alias定义到文件中)

    [root@localhost ~]# alias
    alias cp='cp -i'
    alias egrep='egrep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias grep='grep --color=auto'
    alias l.='ls -d .* --color=auto'
    alias ll='ls -l --color=auto'
    alias ls='ls --color=auto'
    alias mv='mv -i'
    alias rm='rm -i'
    alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde

    一部分来自/root/.bashrc/ (rc-> run command) ,普通用户的.bashrc不包含别名,因为普通用户的.bashrc模板是/etc/skel/.bashrc

    而root这个.bashrc是按照系统完毕就预置的

    [root@localhost ~]# grep '^alias' /root/.bashrc
    alias rm='rm -i'
    alias cp='cp -i'
    alias mv='mv -i'

    一部分来自 /etc/profile.d/目录里的可执行文件

    [root@localhost ~]# grep -rn 'alias' /etc/profile.d/
    /etc/profile.d/colorgrep.csh:9:alias grep 'grep --color=auto'
    /etc/profile.d/colorgrep.csh:10:alias egrep 'egrep --color=auto'
    /etc/profile.d/colorgrep.csh:11:alias fgrep 'fgrep --color=auto'
    ......

     

    ==================================part2=============================

    内置命令bash built-in commands 

    很多种

    第一种:bash自身带的功能 参见 man cd

    第二种:Compound Commands

    例如 for if while 等

    参见man bash

    第三种:function

    [root@localhost ~]# function cd(){ echo 'my function cd:'; }

    有什么函数可以通过set命令找到

    [root@localhost ~]# set | cd
    my function cd:

     

    验证:alias,compound优先级

    [root@localhost ~]# alias if='ls -l'
    [root@localhost ~]# if                   # 证明别名比compound的优先级高
    total 8
    -rw-------. 1 root root 1791 Sep 21 11:00 anaconda-ks.cfg
    -rw-r--r--. 1 root root 1819 Sep 21 03:10 initial-setup-ks.cfg

     

    验证:compound与function的优先级  

    [root@localhost ~]# function for() { echo 'my function for'; }
    [root@localhost ~]# for((i=1;i<3;i++));do echo $i;done        #  执行的仍然是compound命令,证明compound优先级比函数高
    1
    2

    验证:function与内置命令的优先级高

    [root@localhost ~]# function cd() { echo 'my function cd';}
    [root@localhost ~]# cd     # 执行的是自己的函数而不是内置命令cd,证明函数比内置命令优先级高
    my function cd

     

    小结二:

    别名 alias > Compound Commands > function > 内置命令

     

    ==================================part3============================

    当别名和内部命令搜索不到时,找$PATH

    [root@localhost ~]# sed -n 's/:/ /gp' <<< $PATH
    /usr/local/sbin
    /usr/local/bin
    /usr/sbin
    /usr/bin
    /root/bin
    /usr/local/python3/bin

     

    因为这个变量包含的路径太多,每个路径中的可执行文件也很多,如果每次都要搜索每个路径下的所有可执行文件,显然是不明智的

    为了减少$PATH的搜索,上一次搜索的内容能够被下一次执行重用,bash对从$PATH中搜索得出的外部命令建立hash表,用于缓存

    这个缓存是会话级别独立拥有的,不可以对其他终端共享,因为每个用户的$PATH可能不同

    [root@localhost ~]# hash -r          # 清除缓存
    [root@localhost ~]# hostname    # 每执行一次就缓存一次
    localhost
    [root@localhost ~]# hash              # 查看缓存表,发现多了一条缓存
    hits   command
    1      /usr/bin/hostname

     

    验证:hash 与 $PATH的优先级 

    [root@localhost ~]# mv /usr/bin/hostname /usr/sbin/
    [root@localhost ~]# hostname     # 再次执行hostname,没有找到,说明hash寻找路径的优先级高于$PATH
    -bash: /usr/bin/hostname: No such file or directory
    [root@localhost ~]# hash
    hits command
    2 /usr/bin/hostname
    1 /usr/bin/mv

     

    总结命令执行顺序:

    alias   如,alias ls='ls -l'

    compound commands 流程控制关键字  如,if  while for

    function 如,function test() { echo 'my function test'; } 

    function test(){
    read -p 'please input hostname:' name;
    echo $name;
    hostnamectl set-hostname $name;
    }
    
    test

    unset test   # 函数包括定义、调用、取消

    builtin,内置命令 ,如cd ; source 执行脚本 

    hash  缓存命令路径

    $PATH 安装第三方软件包

    三  元字符

    bash中的特殊字符,键盘上能敲出的特殊字符都有其特殊意义,元字符会被shell解释的 

    编程 本质 处理数据的变化或者状态的变化

    1----->2

    500----->1000

    True----->False

    level = 1

    level = 2

    ~ 家目录 区别root用户和普通用户

    [root@localhost local]# cd ~
    [root@localhost ~]# pwd
    /root

     

    ` ` 命令替换  取命令的执行结果

    [root@localhost ~]# res=`ls`        # 取命令运行结果,赋值给变量res,中间没有空格
    [root@localhost ~]# echo $res   # 查看变量res值 
    anaconda-ks.cfg initial-setup-ks.cfg

    $()同上,但它弥补了``的嵌套缺陷,推荐使用

    [root@localhost ~]# res=$(echo $(ls))
    [root@localhost ~]# echo $res
    anaconda-ks.cfg initial-setup-ks.cfg

     

    !取非

    [root@localhost tmp]# ls [abcd].txt    [] 只取中括号里一个字符
    a.txt b.txt c.txt d.txt

    [root@localhost tmp]# ls [a-z].txt       [] 只取中括号里一个字符,从a到z,也包括从A到Z, aAbBcC...z

    [root@localhost tmp]# ls [!0-9].txt     [] 首先取一个字符,且不是0-9数字的
    a.txt b.txt B.txt c.txt d.txt Z.txt

    !历史命名调用

    [root@localhost tmp]# !308
    cd /tmp

    $? 

    0 表示上一条命令执行成功

    非0 表示没有成功

    [root@localhost tmp]# echo $?
    0
    [root@localhost tmp]# djina
    bash: djina: command not found...
    [root@localhost tmp]# echo $?
    127

    @ 无特殊含义

    # 注释

    $ 变量取值

    $() 同 ``

    ${} 变量名的范围

    $[] 整数计算 echo $[2+3] - * / % 浮点数用 echo "scale=3; 10/3" | bc -l

    [root@localhost tmp]# money=10
    [root@localhost tmp]# echo $money
    10
    [root@localhost tmp]# echo 000$money
    00010
    [root@localhost tmp]# echo $money100

    [root@localhost tmp]# echo ${money}1000
    101000

    % 取模;杀后台进程jobs号

    ^ 取反和! 雷同

    & 在后台执行;&&逻辑与运算,如make && make install

    [root@localhost tmp]# pwd && echo 123
    /tmp
    123

    |  管道符号;  || 逻辑或运算,第一个命令执行成功后,停止;第一个命令执行失败后,再执行第二个命令

    [root@localhost tmp]# pwd || echo '123'
    /tmp

     *  乘号

    -  减号;范围;cd - 返回上一个工作目录

    = 赋值 ;== 判断

    [root@localhost tmp]# y=2
    [root@localhost tmp]# x=1
    [root@localhost tmp]# [ $y > $x ]   # 逻辑判断,注意空格隔开
    [root@localhost tmp]# echo $?
    0

    {} 命令列表 ,注意括号内的开头和结尾必须是空格{    ls; cd /;   }

     转义字符

    [root@localhost tmp]# x=1
    [root@localhost tmp]# echo "$x"   # 软引用,区域于' ' 引用
    1
    [root@localhost tmp]# echo "$x"
    $x

    ; 分割多个命令

    : 空命令,返回真

    [root@localhost tmp]# while :;do echo 123;done

    while :;
        do
            echo 123;
            sleep 0.5;
        done

    / 目录分割符

    ?  只匹配一个字符;* 任意字符

    >  比较大小;> 覆盖;>> 追加

    元字符和命令是一个级别的,被bash解析,而正则表达式是被命令解析的

    四  登录shell与非登录shell

     

    登录shell,是通过用户名密码或 su - 获得的shell

    非登录shell,则是通过bash命令和脚本开启的shell环境

    Linux中一切皆文件,shell的属性加载也写到文件里,在登录时就会加载对应的文件的内容来初始化shell环境

    非登录与登录shell区别就在于加载的文件不同,从而导致获得的shell环境不同

     

    登录shell都加载了哪些文件呢 

    测试:

    /etc/profile                 添加   echo '/etc/profile'

    /etc/profile.d/a.sh     新建脚本 a.sh   echo '/etc/profile.d/a.sh'

    ~/.bash_profile          添加  echo '/root/.bash_profiile'

    ~/.bashrc                    添加  echo '/root/.bashrc'

    /etc/bashrc                添加  echo '/etc/bashrc'

    结果 :

    结论:

    1. 登录shell 会加载一些脚本并执行,且脚本之间有顺序

    2. 可以在脚本中定义变量,bash中可以直接使用

    实例:

    1. 在 /etc/profile中添加x=1;y=2  那么,登录之后可以 echo $x;echo $y

    2.  编译安装Python时,更改环境变量  PATH

     

    非登录shell都加载了哪些文件呢

    非登录shell加载的文件就少了很多,并且顺序也不同

     

    所以,我们想要固化一个配置在那种登录下有效

    将环境变量设置在 $HOME/.bash_profile

    不管那种登录都想使用的变量就设置在 $HOME/.bashrc

     

    补充:

    命令补齐TAB键
    简化输入 提示 防止书写错误


    历史记录
    上下键查
    history 查询 用!ID 调用
    ctrl+r 输入匹配

    快捷键
    CTRL+A 行首
    CTRL+E 行尾
    CTRL+U 删除自光标到行首串
    CTRL+K 删除自光标到行尾串
    CTRL+L 清屏

     

    更多内容请参考

    http://www.cnblogs.com/linhaifeng/p/6592572.html 

  • 相关阅读:
    TextView文字排版问题:
    Cent OS 6 主机名设置
    windows server 时间同步
    DELL服务器SAS 5 I_R 完全配置手册
    SAS 5/iR Adapter 驱动下载
    U盘加载硬盘控制卡驱动安装Windows 2003 指南
    邮件客户端导入邮件通讯录地址薄
    Symantec System Recovery
    windows server 备份与还原
    Acronis 备份使用
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/7582109.html
Copyright © 2011-2022 走看看