认识bash shell_Little BigUs的博客-程序员宅基地

技术标签: linux学习  电脑知识  linux  bash  开发语言  

认识 bash shell

Bash shell

我们知道管理计算机硬件的是kernel,而我们user是通过shell和kernel进行沟通的,那到底什么是shell,什么是bash呢?

什么是shell?

你可以理解shell就是指令,没错,就是指令,这指令是用来干嘛的呢?当然是用来控制计算值按照我们想要的动作工作啦,也就是说其实shell就是用户用来控制计算机工作的指令。

我们知道直接控制计算机硬件的是kernel,而我们用户则可以通过shell控制kernel从而间接地控制硬件工作。

什么是bash?

Bash是一个命令处理器,通常运行于文本窗口中,并能执行用户直接输入的命令。全称: Bourne-Again Shell。有没有发现什么,没错,bash也是一种shell,其实bash只是shell的一种,而我们学习的Linux上的shell就是bash。

我们查看/etc下的shells文件就可以知道linux下可以使用的各种shell。

不同的shell的功能是差不多的,只是使用语法有不同而已。我们学习使用最广泛的bash。

bash shell的内建命令:type

通过 type 指令 例如 type cd 可以知道一条指令是不是bash的内建指令

shell的变量功能

通过使用变量,我们可以用一个简单的内容来表示复杂的内容或者是变化的内容

例如前面讲过的PATH就是一个变量 ,我们通过echo $PATH就可以打印这个变量。 为了区别与自订变量的不同,环境变量通常以大写字符来表示呢!

变量的取用与设定

通过echo可以取用变量,echo $变量名

通过=修改某个变量的内容,我们知道在其它语言中=是赋值符号,在这里也是差不多赋值的意思,例如 qqq=“qweqweq”,然后

echo $qqq ,就会输出qweqweq。

注意

  1. 等号两边不能接空格!!!

  2. 变量名只能有英文字母和数字且不能以数字开头

  3. 若有空格符可以使用双引号『 " 』或单引号『 ’ 』来将变量内容结合起来,但须要特别留意, 双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符;

    什么意思? 例如 我们定义qqq=" P A T H " , w w w = ′ PATH" , www=' PATH",www=PATH’,然后echo $qqq 和echo w w w 。 你 会 发 现 前 面 是 输 出 P A T H 变 量 的 内 容 而 后 面 是 输 出 www。你会发现前面是输出PATH变量的内容而后面是输出 wwwPATHPATH这几个字符

  4. 若该变量为扩增变量内容时,则需以双引号及 变 量 名 称 如 : 『 " 变量名称 如:『 " "PATH":/home』继续累加内容;

  5. 若该变量需要在其它子程序执行,则需要以 export 来使变量变成环境变量, 如『export PATH』;

  6. 取消变量的方法为:『unset 变量名称』。

自订变量转成环境变量: export

我们通过 less .bashrc查看家目录下的文件,可以看到一些exprot命令,这就是以当前用户登录bash时会导入的环境变量

变量键盘读取、数组与宣告:

  • read 例如read qqq就是等待用户从键盘输入作为qqq变量的内容

    -p 后面可以接提示字符

    -t 后面可以接等待的时间

    提示使用者 30 秒内输入自己的大名,将该输入字符串做成 named 变量

     read -p "Please keyin your name: " -t 30 named
     Please keyin your name: VBird Tsai
    
  • declare/typeset 宣告变量的属性

  • 数组属性array说明

    通过arr[0] = “123”;定义数组,通过echo ${arr[0]}取数组

命令别名设定: alias, unalias

登录讯息显示数据: /etc/issue, /etc/motd

还记得我们在终端机接口 (tty1 ~ tty6) 登入的时候,会有几行提示的字符串吗? 那个字符串写在哪里啊?呵呵!在 /etc/issue 里面啊!我们可以自己修改哦,试试修改看看吧。

issue 内的各代码意义

  • \d 本地端时间的日期;
  • \l 显示第几个终端机接口;
  • \m 显示硬件的等级 (i386/i486/i586/i686…);
  • \n 显示主机的网络名称;
  • \o 显示 domain name;
  • \r 操作系统的版本 (相当于 uname -r)
  • \t 显示本地端时间的时间;
  • \s 操作系统的名称;
  • \v 操作系统的版本。

还有个 /etc/issue.net 呢!这是啥?没啥啦!这个是提供给 telnet 这个远程登入程序用的。 当我们使用 telnet 连接到主机时,主机的登入画面就会显示 /etc/issue.net 而不是 /etc/issue 呢!

至于如果您想要让使用者登入后取得一些讯息,例如您想要让大家都知道的讯息, 那么可以将讯息加入 /etc/motd 里面去!

书上是这么说的,但是我在ubuntu18.04中并没有找到这个文件,上网查后发现想要自定义登入欢迎信息应该先进入/etc/update-motd.d目录。可以发现很多数字开头的文件。通过file命令查看可以发现都是shell script,也就是shell脚本。其实在我们登录的时候会按照前面数字从小到大的顺序执行这些script,所以我们可以自己创建一个文件,例如99-welcome,然后编辑文件如下

#!/bin/sh      
echo hello,welcome

上面第一行是固定格式,下面的echo我们都知道是输出内容,编辑完后 :wq!保存并退出,然后不要忘记更改文件权限了,要让他可执行。chmod 755 11-welcome。这时候再重写登录,你就能看到自定义的欢迎语了。

我按照上面的做法确实能显示欢迎语,但是我无法修改,反正就是达不到我想要的效果。

推荐一篇博客

  • sudo chmod -x /etc/update-motd.d/* 禁用所有的欢迎语

  • sudo apt install inxi screenfetch ansiweather 安装需要的软件

  • Create a new script

    创建01-custom的文件 代码如下:

    #!/bin/sh
    echo "GENERAL SYSTEM INFORMATION"
    /usr/bin/screenfetch
    echo
    echo "SYSTEM DISK USAGE"
    export TERM=xterm; inxi -D
    echo
    echo "CURRENT WEATHER AT THE LOCATION"
    # Show weather information. Change the city name to fit your location
    ansiweather -l bratislava
    
  • Make this script executable

    sudo chmod +x /etc/update-motd.d/01-custom
    

然后登录就可以看到一个炫酷的登陆界面了。但是我还是无法添加自己的欢迎语。。。很郁闷。用echo也不行,printf也不行。过了一会儿修改的内容又可以了,搞不懂啊,难道是没有同步?而且好像搞了这个花里胡哨的东西后连接变慢了。。。

我去,我还是卸载了吧。

终于可以显示自定义的欢迎语了,但是这黑底白字有点普通啊,调一下字体颜色。教程

环境设定档: bashrc, ~/.bashrc, ~/.profile, profile…,/etc/inputrc, source

要注意的是,在指令列输入的变量也好、命令别名也罢, 都是针对该次登入的设定而已,所以只要您一注销,那么上次的设定值就会不见去! 因此,我们需要有几个档案来帮助我们,每次登入的时候,就已经帮我们搞定了环境的设定啰!

  • 系统设定值

    所谓的系统设定值,也就是说每个使用者进入到 bash shell 之后,会先读取的设定档案! 预设的设定档案有下列几个:

    • /etc/sysconfig/i18n 。i18n是国际化的意思,18好像是中间省略了18个单词,Ubuntu似乎找不到这个文件

    • /etc/profile

      # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
      # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
      
      if [ "${PS1-}" ]; then
        if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
          # The file bash.bashrc already sets the default PS1.
          # PS1='\h:\w\$ '
          if [ -f /etc/bash.bashrc ]; then
            . /etc/bash.bashrc
          fi
        else
          if [ "`id -u`" -eq 0 ]; then
            PS1='# '
          else
            PS1='$ '
          fi
        fi
      fi
      
      if [ -d /etc/profile.d ]; then
        for i in /etc/profile.d/*.sh; do
          if [ -r $i ]; then
            . $i
          fi
        done
        unset i
      fi
      

      我们可以看到$和#,是不是这个提示符是在这里设置的呢?我们不妨修改一下啊,然后会发现提示符并没有改变,别忘了撤销你的修改哦!

    • /etc/bashrc

      这个档案在规划 umask 的功能,也同时规划出提示字符的内容 (就是里头那个 PS1 啦!) 。特别留意的是,这个档案在不同的 Linux distribution 里面,摆放的位置可能不太一样呢! 所以需要查询一下才行呦!

      通过locate bashrc寻找位置,然后打开文件我们可以发现有如下的语句

      if [ "$USER" = "root" ]; then
      	printf "%s" "#";
      else
      	printf "%s" "\$"
      fi
      

      难点这里可以修改提示符?我们不妨试试。发现也不行,记得还原改动哦!

    • /etc/profile.d/*.sh

      /etc/profile.d 是一个目录,里面针对 bash 及 C-shell 规范了一些数据。 你可以自行设定一些 *.sh 的文件名的档案来书写自己的系统设定值喔!

    • /etc/man.config

      在ubuntu下找不到这个文件

  • 个人设定值

    前面都是系统设定值,但是对于我们每一个用户都有自己的习惯与喜好,我们的个人设定值该怎么设置与存储呢?既然是用户自己的,那文件肯定位于用户的家目录下。我们在家目录下 ls -a就可以看到很多的个人设置值。

    .bash_history .cache .config .mysql_history .pip .ssh .viminfo .Xauthority
    .bashrc .cmake .dbus .gnupg .local .pearrc .pydistutils.cfg .sudo_as_admin_successful .vnc

    • ~/.bashrc

      我的个人化设定值都会写在这里

    • ~/.bash_profile, ~/.bash_login, ~/.profile

      ubuntu不在家目录下,使用 locate .bash_logout可以看到它的位置,不要忘记locate这条命令哦。

      这三个档案通常只要一个就够了(ubuntu下是.profile),一般预设是以 ~/.bash_profile 的檔名存在。 会有这么多的档案,其实是因应其它 shell 转换过来的使用者的习惯而已。 这个档案可以定义个人化的路径 (PATH) 与环境变量等等。不过,还是有顺位上的差异, bash 启动时,会先去读取 ~/.bash_profile,找不到时,就去读取 ~/.bash_login ,然后才是 ~/.profile。

    • ~/.bash_history

      顾名思义,bash的历史记录

    • ~/.bash_logout

      这个档案则记录了『当我注销 bash 后,系统再帮我做完什么动作后才离开』的意思。ubuntu不在家目录下,使用 locate .bash_logout可以看到它的位置,不要忘记locate这条命令哦。

在我们登录bash后这些设定文档是如何读取的呢?

  1. 先读取/etc/profile,再根据它的内容去读取其他的设定档
  2. 根据不同的使用者,到使用者家目录去读取 ~/.bash_profile 或 ~/.bash_login 或 ~/.profile 等设定档;
  3. 根据不同使用者,到他家目录去读取 ~/.bashrc

所以说,最终读取的才是最后的设定

书上是这么说的,但我感觉Ubuntu好像不是这个读取顺序,为什么这么说呢,我原来的.bashrc内容如下

#set oracle jdk environment\n
export JAVA_HOME=/usr/java/jdk\n
export JRE_HOME=\${JAVA_HOME}/jre  \n
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib\n
export PATH=${JAVA_HOME}/bin:\${PATH}

export HISTTIMEFORMAT="%d/%m/%y %T "

export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

这个文件可能被我修改过,导致第5行$前面多了个\,所以PATH变量只有JAVA_HOME了,我们这时候使用source .bashrc加载资源,这时候任何命令包括ls都无法执行了,因为找不到路径。但是我们重新登录一下就又可以执行ls了,所以我猜测.bashrc并不是最后加载的。

而且我发现似乎这个文件并不会加载,每次需要我自己加载才会生效。而且好像连/etc/skel/.bashrc也不会自己加载,需要我手动加载后才会生效。我们查看/etc/profile发现确实没有加载的代码。

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "${PS1-}" ]; then
  if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

加载的是/etc/bash.bashrc和执行/etc/profile.d下的脚本。我们修改一下文件如下:(仿写的,好没学到脚本)

if [ "${PS1-}" ]; then
  if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
    if [ -f /etc/skel/.bashrc ]; then
      . /etc/skel/.bashrc
    fi
    if [ -f /home/ubuntu/.bashrc ]; then
      . /home/ubuntu/.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

其实就是加了两个判断语句,如果文件存在,则加载。还有就是那个用户的配置文件我是写死的,只加载指定用户的配置文件,这肯定是不行的,我们应该有个循环,加载所有用户的配置文件,不过这都是后面的事情了。

万用字符与特殊符号

  • *:万用字符,代表 0 个或多个字符(或数字)
  • ?:万用字符,代表『一定有』一个字母
  • #:批注,这个最常被使用在 script 当中,视为注释!
  • :转义符
  • |:分割两个管线命令的界定
  • ;:连续性命令的界定(注意!与管线命令并不相同)
  • ~ : 使用者的家目录
  • $:亦即是变量之前需要加的变量取代值
  • &:将指令变成背景下工作
  • !:逻辑运算意义上的『非』 not 的意思!
  • /:路径分隔的符号
  • > , >> : 输出导向,分别是『取代』与『累加』
  • ’ : 单引号,不具有变量置换的功能
  • " : 具有变量置换的功能!
  • ``:两个『 ` 』中间为可以先执行的指令!也可以用$()取代
  • () : 在中间为子 shell 的起始与结束
  • [] :在中间为字符的组合
  • {} :在中间为命令区块的组合!
  • Ctrl + C 终止目前的命令
  • Ctrl + D 输入结束(EOF),例如邮件结束的时候;
  • Ctrl + M 就是 Enter 啦!
  • Ctrl + S 暂停屏幕的输出
  • Ctrl + Q 恢复屏幕的输出
  • Ctrl + U 在提示字符下,将整列命令删除
  • Ctrl + Z 『暂停』目前的命令

数据流重导向

> , >> ,表示将符号左边的导入符号右边,第一个符号是覆盖,第二个是追加

但是上面的两个符号只会重定向正确的输出,如果想要重定向错误的输出则需要 2> 。用法和上面一样哦。

那么那个 < 又是什么呀!?呵呵!以最简单的说法来说, 那就是『将原本需要由键盘输入的数据,经由档案来读入』的意思

命令执行的判断依据: ; , &&, ||

在某些时候,我们希望可以一次执行多个指令,例如关机时,希望我可以先执行两次 sync ,然后才 shutdown 计算机,那么可以怎么作呢?这样做呀sync; sync; shutdown -h now

在指令与指令中间利用分号 ( 来隔开,这样一来,分号前的指令执行完后, 就会立刻接着执行后面的指令了。

如果有c语言基础的就会知道&&是强与,也就是如果前面不符合条件的话后面不会进行执行判断。在bash也是一样,如果我们需要在条件成立的情况下玩成某条指令的话可以把条件放前面,指令放后面。 || 也是一样的,如果前面满足了就不会执行后面的指令。

管线命令

管线命令使用 | 符号,使用管线命令的几条指令,左边指令的输出作为右边指令的输入。

撷取命令: cut, grep

  • cut : cut - remove sections from each line of files

    更多的信息可以使用man cut查看

  • grep : grep, egrep, fgrep, rgrep - print lines matching a pattern

    也就是从一行中找到我们需要的部分

双向重导向: tee

在前面我们讲了 > 可以将输出重导向到指定的文件中去,但是如果有时候我们既希望导入到文件,又希望能在屏幕上看到呢?这时候就要使用 tee命令了

tee - read from standard input and write to standard output and files

-a, --append

例如前面我们通过ls > output就可以将输出导入到output文件,此时屏幕上不会显示任何东西,而使用ls | tee output2可以将ls的内容同时输出到文件和屏幕。

查看变量:set,env

使用set命令可以查看所有的变量,使用env命令可以查看所有的环境变量。

取消变量:unset

取消 别名:unalias

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_45972156/article/details/123547363

智能推荐

樱陀花园10月份活动策划_chikuang0023的博客-程序员宅基地

樱陀花园10月份活动策划--魔方、围棋课程开班一、活动安排时间:2015年10月7号之后(具体时间据天气)地点:樱陀花园小区社区居委会前广场参与人员:樱陀花园社区儿童二、活动内容参加活动之前必须报名、填写报名表格(活动现场设报名点)儿童独立或者在家长辅助下还原 二阶魔方、三阶魔方。根据完成情况...

Redis 的主从同步(复制)_顾思鸣的博客-程序员宅基地

Redis 的主从同步(复制)Redis 的主从同步(复制)比奇小说网 https://m.biqi.org/什么是主从同步(复制)假设有两个 redis 实例 ⇒ A 和 BB 实例的内容与 A 实例的内容保持同步那么称 A 实例是主数据库,B 实例是从数据库这个过程称为主从同步为什么要使用主从同步(复制)防止发生单点故障扩展内存如何开启/关闭主从同步开启同步...

关于承诺的想法-JavaScript_weixin_26750481的博客-程序员宅基地

Promises are just wrappers over async units of works (or operations), they’re used to represent future values. 承诺只是工作(或操作)异步单元的包装,它们用于表示未来的价值。 A promise can be on multiple states: 一个承诺可以处于多个状态: Pend...

【默默努力】h5-game-blockBreaker_weixin_30869099的博客-程序员宅基地

先放下游戏的效果,我不太会玩游戏然后放下无私开源的作者大大的地址:https://github.com/yangyunhe369/h5-game-blockBreaker这个游戏的话,我觉得应该是如果如果球跟砖碰到了,那么这个砖就消失,然后得一分,然后这个球就会以竖直的相同的角度返回,如果球到了发射台,就会以在发射台的角度返回去,如果球没有碰到发射台,那么球就沿着坠落的方向消失,...

cxf-rs 和 swagger 的点_Just do it的博客-程序员宅基地

1. 从web.xml 说起 &lt;servlet&gt; &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt; &lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt; ...

sublime配置_weixin_34293059的博客-程序员宅基地

sublime 确实招人喜欢, 大有全面超越vim的趋势, 大胆猜测原因有:2.0.1版下载地址 http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%202.0.1%20Setup.exe1.默认配色就很酷; 也跨平台. 2.没有工具条, 留给编辑区的区域很大, 可以专注于代码. 3.不必过多使用鼠标,又不用像vim, 你必须记住太多的快捷键...

随便推点

【数据库(二)】SQL语言以及DQL的学习_黑黑白白君的博客-程序员宅基地_dql和sql

文章目录1)SQL语言1.1 什么是SQL语言?1.2 为什么需要SQL语言?可移植性:稳定性:易于性能增益:1.2 SQL语言的分类DQL(Data Query Language):DML(Data Manipulate Language):DDL(Data Define Languge):TCL(Transaction Control Language):2)DQL语言2.1 基础查询语法:特点:常见使用:选择特定的列:选择全部列:查询常量、表达式、函数、方法:起别名:去重:配合+号:拼接:2.2 条件

计算机统计字符数,如何在Word中统计相同字符(文字)出现的个数 -电脑资料_高傲的大白杨的博客-程序员宅基地

大家都知道,在Word中我们可以统计一篇文章字符的总个数!但是,却不知道是啥原因,不知道是Word觉得此功能太简单了,还是忽略了这一点;却没有统计相同字符个数的功能!但这未提供的功能却广为大众所需,很多人不仅想知道总的有几个字,更想知道相同的字符有几个!为此,本文就提供这种功能—技术文章,为方便大家一起学习!如果您有这方面的需求,请对下文仔细过目至少两遍!此功能的宗旨是:通过宏来实现,并且将宏名放...

mysql数据库大数据量的查询优化和分页测试_yangcbyang的博客-程序员宅基地

http://blog.sina.com.cn/s/blog_438308750100im0b.html有什么问题:[email protected] 于堡舰 我原来的公司是一家网络游戏公司,其中网站交易与游戏数据库结合通过ws实现的,但是交易记录存放在网站上,级别是千万级别的数据库是mysql数据库.   可能有人会问mysql是否支持千万级数据库,还有既

无法更改列 'xxx',因为它是 'REPLICATED'。_半世笙箫的博客-程序员宅基地

当我在更新表的列名称时,遇到报错‘无法更改列 ‘name’,因为它是 ‘REPLICATED’。’ 查看数据库服务器,并无相关的发布和订阅存在。在网上搜索相关错误信息,发现有网友之前同样遇到过这种报错,原因是之前进行过订阅复制,后续删除时没有删除干净,需要使用EXEC SP_REMOVEDBREPLICATION ‘发布数据库名称’来强制删除发布。 在数据库中运行上述语句后...

java调动jquery_笔记之_Java整理jquery_Clover青子的博客-程序员宅基地

$.extend扩展Jquery的bin绑定事件,unbind取消所有事件http://jquery.cuishifeng.cn/Jquery学习地址:http://www.runoob.com/jquery/jquery-plugin-validate.htmlJquery学习地址:http://www.haorooms.com/post/jquery_selecter_zj使用ajax的jso...

linux 5.9 32位 下载,Linux Kernel 5.9.2_苏友学的博客-程序员宅基地

Linux Kernel 5.9.2是一款非常经典好用的操作系统,之前系统中的各种漏洞都已经修复了,且最新版本的LinuxKernel系统的漏洞也都查清了,用户们可以放心的下载和使用哦~Linux Kernel 5.9.2漏洞详情:1、CVE-2020-26088 严重程度:高net / nfc / rawsock.c中的NFC套接字创建中缺少CAP_NET_RAW检查,本地攻击者可以绕过安全机制...

推荐文章

热门文章

相关标签