zoukankan      html  css  js  c++  java
  • fw: bash ubuntu

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://kimva.blogbus.com/logs/19988697.html

    GNU/Linux支持多种版本的shell. 但默认的是bash. /etc/shells文件列出了本机linux系统支持的shell类型. /etc/passwd中列出了用户默认的登录shell.

    从当前shell转换到另一种shell: 直接在命令行输入对应的shell程序名.如:
    sh
    sh-3.00$
    提示符变了, 要退回到之前的bash, 可输入exit或使用C-d组合键.

    bash的特色

    1, 命令行参数: sh只能传送单字符参数(可通过内置的set命令配置), bash还可以传送字符串参数.
    2, 启动配置文件: bash启动时, 依次读取启动文件, 这样可以在bash启动时完成一些默认的配置工作. (关于bash配置文件, 后面再讨论).
    3, bash是交互性shell.
    4, 条件表达式.
    5, shell算术.
    6, 别名.
    7, 数组
    8, 目录栈.
    9, 受限版的bash: rbash.

    bash命令的执行

    bash能够识别要执行内容的类型: 是系统中的可执行程序, 还是bash的内置命令, 或者是一个bash脚本? 根据这些类型, bash的执行方式有所不同:

    1, 可执行程序: 遵循fork-exec形式, 它fork出一个子bash进程, 父bash和子bash仅进程号不同. 注意这种情况下, 父进程等待子进程执行, 子bash执行完毕退出后, 父bash重新执行. 程序对子bash的环境做出的更改不会影响父bash.

    2, bash内嵌命令: bash直接执行命令, 不新生成一个进程.

    3, bash脚本: 分两种情况:
    (1) 如果直接执行脚本, 比如: $ ./foo.sh , 此情况与执行可执行程序相同, 生成的子bash进程一次从脚本读取一行命令来执行, 如同用户从键盘输入命令. 

    (2) 如果执行 $ source ./foo.sh, 这相当于执行bash的内嵌命令, 也可以起到执行脚本命令的作用, 但不生成新的bash. 所以如果需要在脚本中更改bash环境变量的话, 要用source命令! 直接运行脚本只能更改fork出的子bash的环境变量, 运行结束后, 子bash退出, 父bash的环境变量不受影响.


    编写bash脚本

    1, 推荐使用能够显示bash语法高亮的编辑器, 比如emacs, gedit, vim...

    2, 自己编写的脚本怎样命名, 放在什么地方?
    命名: 为了避免自己写的脚本与系统命令重名, 建议shell脚本以.sh结尾. 但自己写的脚本还是可能与系统自带的脚本重名, 建议命名前通过$ which scriptname.sh (或者whereis, locate)来查看.

    位置: 可以将自己写的脚本放在一个合适的目录中, 比如~/script. 

    Unix/Linux不利用文件扩展名来判断文件类型. 要想知道文件类型, 可使用file命令.

    3, 如何执行脚本?
    (1) 脚本可以像命令一样被执行:
    /bin/bash file.sh (不需要file.sh的可执行权限)

    如果你懒得输入/bin/bash, 可以采取下面的两种方法:
    如果脚本被集中放置在~/script目录, 可以将该目录添加到PATH中再直接调用
    export PATH="$PATH:~/script"
    由于脚本所在的目录在PATH环境变量中, 所以可直接运行: $ file.sh (需要file.sh有可执行权限)

    如果想执行当前目录的脚本, 可以运行$ ./scriptname.sh  (需要file.sh有可执行权限)
    方法(1)使bash新生成一个子bash来执行, 在此情况下, 脚本对环境变量的更改只对子bash有效.并且在执行脚本文件之前必须更改权限(指明shell路径时不用), 让脚本具有相应的执行权限.
     
    (2) 可使用source命令来直接执行脚本(可用'.'来代替source). 它与上面的方法有两点区别:
    1, 脚本文件不需要执行权限.
    2, 就在当前bash中执行, bash不会新fork一个子bash来执行它, 所以脚本对环境变量的更改会影响到当前bash.

    推荐使用./file.sh在当前目录执行脚本, 这样可以避免误调系统其他位置的重名脚本. 如果需要更改当前shell的环境变量, 则使用source命令. 不推荐修改环境变量: 这会造成系统的安全隐患.

    当你确认脚本运行无误, 而且需要经常执行它时, 可将它copy到合适的系统执行目录, 比如/usr/bin, /usr/local/bin 或者~/bin(需修改PATH)中. 然后向调用命令一样执行它.


    脚本结构

    脚本开头第一行指定运行脚本的shell, 一般指定为bash:
    #!/bin/bash

    bash脚本中的注释以'#'开头, #之后到行尾的内容为注释, 在执行时会被bash忽略. (脚本中不能再在同一行的注释之后添加命令, #之后到行尾的内容都会被bash忽略!)  但脚本开头的#!是个例外!

    在脚本结尾的最后一行, 一般包含一个 "exit 0" 语句(0表示执行成功). 它返回一个值. 注意: 在交互式bash中, 这条命令没什么用处. 当它所在的脚本被被的脚本调用时, 就能确定被调用的脚本是否正确执行了. 你的脚本在将来可能被别的脚本所调用, 所以最好在脚本末尾包含这条语句. 这也是编写可重用脚本的一个好习惯.


    调试脚本

    调试整个脚本

    最通用的方法是新调用一个bash, 以调试选项"-x"来执行脚本: $ bash -x scriptname.sh
    这种情况下, 新bash在显示每个语句生成的结果之前打印出该语句(以+开头), 这样易于我们对比语句和执行结果.

    调试脚本的部分内容

    只需在脚本中你想调试的语句之前添加: set -x, 然后在结尾添加: set +x. 可以把这两条语句当作"调试开关", 在脚本中多次调用.

    调试选项归纳如下:
    Short notation    Long notation    Result
    set -f         set -o noglob    Disable file name generation using metacharacters (globbing).
    set -v         set -o verbose    Prints shell input lines as they are read.
    set -x         set -o xtrace    Print command traces before executing command.

    注意, -为打开启用调试,+为关闭调试,这容易混淆.

    这些选项不光可以添加到脚本文件中, 还可以直接在命令行中指定. 
    e.g:
    set -x
    ls
    看看结果吧 :)


    bash环境

    启动配置文件的读取

    首先要理解: 交互式bash和非交互式bash(interactive& non-interactive)

    交互式shell: 用户输入命令给shell执行, shell将执行的结果通过输出反馈给用户. 

    非交互式shell: 命令(脚本)在后台执行, 执行过程中不读取用户输入, 也不反馈执行信息.(执行完毕后可能会显示一些信息).

    如何判断某个shell是不是交互式的呢? 可以运行 $ echo &-, 若输出中还有小写字母'i', 则是交互式shell. 一般而言, terminal或console都是交互式shell, 而shell脚本在执行时执行它的shell就是非交互式的.

    交互式bash还有两种调用方式: login和non-login. 

    login: 我们在文本模式下登录console时, bash提示输入用户名和密码, 此时的bash就是login的.

    non-login: 在图形模式下, 打开一个 terminal, 不需要输入用户明或密码, 此时调用的bash就是non-login的.

    根据login和non-login的区别, bash在启动时读取不同的配置文件:

    login:
    1, 读取/etc/profile: 它是所有用户, 所有shell的启动配置文件. /etc/profile还会读取/etc/bash.bashrc, 它是所有用户的bash启动配置文件.

    2, 读取~/.bash_profile, 若它不存在, 则读取~/.bash_login 同样, 若前两者不存在, 读取~/.profile. 

    3, 在logout时读取~/.bash_logout

    non-login:
    读取~/.bashrc.

    可以自行在上述的配置文件的末尾添加echo语句, 这样在console中登录或者打开一个终端时就能显示配置文件的读取信息. 上面的总结基于Ubuntu, 各发行版可能情况不同.

    non-interactive:
    读取的文件由BASH_ENV定义. 这些文件要用全路径, 因为无法用PATH变量来搜寻这些文件.


    bash的初始化文件

    一, 针对整个系统所有用户的login配置文件.

    1, 针对整个系统的所有用户, 所有shell的配置文件  /etc/profile
    # System wide environment and startup programs, for login setup

    注意: 该配置文件被交互式login shell读取, 以bash为例, 在图形模式下打开terminal时是交互式non-login的, 所以不会读取/etc/profile: 运行 $ bash, 不会读取/etc/profile. 但如果以 $bash --login, 则会读取.

    在字符界面下, 最初登录时会读取/etc/profile. 登录后的情形等同于图形界面的terminal.

    2, 针对整个系统所有用户, bash的配置文件 /etc/bash.bashrc
    它一般会被/etc/profile读取以配置bash环境. 

    二, 针对单个用户的login配置文件
    这些配置文件默认位于用户的home目录, 以.开头, 是隐藏文件. 如果它们不存在, 可以创建它们.

    1, ~/.bash_profile
    This is the preferred configuration file for configuring user environments individually. In this file, users can add extra configuration options or change default settings.

    与/etc/profile相同, ~/.bash_profile在交互式, login情况下被读取.
    如果~/.bash_profile不存在, 则读取~/.bash_login, 若~/.bash_login也不存在, 则读取~/.profile.

    三, 针对单个用户的login-out配置文件
    在logout时候, bash读取~/.bash_logout文件.

    四, 针对单个用户的non-login配置文件
    ~/.bashrc
    在图形模式下, non-login bash更为广泛地存在: 打开一个terminal一般不会读取/etc/profile或~/.bash_profile文件, 因为图形模式下打开终端时是non-login的. 这种情况下通过~/.bashrc来配置.
    ~/.bashrc是否会被读取的情况等同于/etc/profile和~/.bash_profile.

    这样, 我们就知道在定制bash环境时, 如何针对自己的需要修改这些配置文件了:

    login情形下, 针对所有用户的定制: /etc/bash.bashrc;  针对单个单个用户的定制: 修改~/.bash_profile

    non-login情形下: 针对所有用户的定制: /etc/bash.bashrc; 针对单个用户的定制:  修改~/.bashrc

    注意: /etc/bash.bashrc会被login或non-login的bash读取!

    对这出配置文件进行修改后, 可以重登录, 或者新开一个bash, 或者使用source命令来使它们生效.

    有时候可能记不清到底是哪些配置文件被读取, 可在上述的文件末尾添加一条echo语句, 显示它是否被调用. 然后打开一个terminal或者进入console看看, 就知道哪些配置文件被调用, 以及它们的调用顺序.

  • 相关阅读:
    机器学习——ALS算法
    机器学习——Kmeans算法
    机器学习——欧式距离和余弦距离
    《JAVA策略模式》
    POSTGRESQL 数据库导入导出
    SpringBoot解决前后端全局跨域问题WebMvcConfigurer
    java读取json文件进行解析,String转json对象
    docker: Error response from daemon: Conflict. The container name "/mysql8.0" is already
    学习笔记:shell 中 [-eq] [-ne] [-gt] [-lt] [ge] [le]
    linux 判断一个用户是否存在
  • 原文地址:https://www.cnblogs.com/dracula/p/1981343.html
Copyright © 2011-2022 走看看