关闭

linux 认识与学习 bash

558人阅读 评论(0) 收藏 举报

shell 就是“壳”啊 ,依靠它与内核打交道。

其实壳程序的功能只是提供用户操作系统的一个接口,  因此这个壳程序需要可以呼叫其他软件

我们之前学习的命令,例如 man, chmod, chown 等等,这些指令都是独立的应用程序,但是我们可以透过壳程序(就是指令列模式)来操作这些应用程序,

让这些应用程序呼叫核心来运作所需的工作

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

- 认识 Bash 这个 shell

shell 分类 :

  /bin/bash          linux 预设的 shell

  /bin/ksh            ( 由 AT&T Bell lab 发展而来, 兼容 bash )

  /bin/tcsh           ( 整和 c shell, 提供更多的功能 )

  /bin/zsh            ( 基于 ksh , 功能强大 )

shell功能 :

  • history
  • tab
  • alias
  • job control ( 前景背景控制 )
  • shell scripts
  • 通配符 ( 例如 * )

history :   保存使用过的命令的功能 .

n : 理出最近的 n 个命令

-c 将 shell 中的 所有 history 删除

-a : 将目前的 history 指令增加到 hisfiles 中,若hisfiles不存在,则写入 ~/.bash_history

-r : 将 hisfiles 中的指令读到 shell 中

-w : 将目前 shell中的指令写入 hisfiles

!67 执行第 history 中第 67 行指令

  命令档案补全功能 Tab 

  命令别名设置 : alias (  alias lm='ls -al' 注意等号左右不能有空格

  工作控制, 前景,背景控制

  shell script 

  control + c 停止命令, control + d 退出

  通配符 

  type   ( 查看是否为内建指令 ) bash 内建了一些指令 , 例如 cd , type cd 显示是一个内建指令, type mkdir 则显示 mkdir 文档的路径

  ( 当指令过长时, 可以使用 \ 来换行 )    例如 cp /tmp/asdf1 /tmp/asdf2 /tmp/asdf3 \

   /root   ( 注意此行的提示符号是继续上一样 > )

变量的取用与设定: ( 间接的力量 )

  echo $PATH ( 变量前一定要加 $ )

  编写 shell script 时, 路径使用变量是一个好办法,  当想变换路径时, 就使用变量替换. 例如经常去 /tmp/asdf这个目录下工作, 就可以设定 work="/tmp/asdf" , 下次直接 cd $work

  变量赋值 : my=ABC

      其中 = 等号左右不能有空格,  my=ABC

      如果内容有空格, 则需要用单引号或者双引号 '' , "" 括起来   var='lang is $LANG'

      可以使用 \ 将特殊字符如回车, $ 等等变成一般字符  my=\$ABC

      当执行指令还需要用到其他指令时, 可以借助 $ 或者 `` ( 键盘上1左边的键进行设置 )  verson=$(uname -r) ; echo $verson
      myname=${name}hehe  // 返回的结果是leonhehe

      若变量扩增内容 : PATH="$PATH":/home 也可以是 PATH= ${PATH}:/home

      export 变量 使变量变成环境变量

     export 直接接变量名称, 前面不需要 $ 变量符号, 例如 export name

      一般大写为系统默认变量, 小写为个人设置变量 .

      unset my 取消变量

      '' , "" 单引号 双引号的区别 , 双引号可以保有变量的内容, 而单引号不可以 echo "$name its me" 这的变量name的内容被保有, 输出 my its me 但是如果使用单引号, 输出

              $name its me.

   

      `` ( 1左边键盘的 ) , 在这个符号下的命令会先被执行, 并将执行结果作为输入信息的一部分 .

     引号规则为先遇到先引用 例如 myname = 'abc's name' 失败了, 可以使用的办法是 myname =" abc's name" ok , 由于双引号是成对出现,并且是先引用,所以没问题

     另外可以选择的办法是逃脱 : myname = 'abc\'s\ name' ( 注意 因为输入字符中有空格, 所以必须要加引号 )

     变量累加时,最好的办法是变量两边+{} 例如 PATH = ${PATH}:\bin

    bash 进入子 shell . ( 进入子程序后,比如刚刚设定的变量,不可以使用了,退出子程序后,又可以看到该变量了 )


 

环境变量 :    

  env : 查看环境变量

  $ 是一个变量, 表示目前这个shell的线程号,即PID

  ? 是一个变量,  echo $? 返回上一个指令执行的回传值.

  set : 设置shell , 如果只是 set 可以将所有的变量显示出来。

  export : 将变量设置成环境变量  export 变量名 ( 子程序可以继承父程序的环境变量, 注意是环境变量而不是一般变量 ) 环境变量与自定义的变量的区别就是,是否被子bash所继承。

locale 查看语系内容。 locale -a 查看所有的语系,其中含有支持中文的

变量的键盘读取

  read : 读取来自用户输入的变量 , read atest , ( 用户输入 this is a test ) echo $atest , ( 结果 this is a test ) -p 提示信息 , -t 读秒(不会一直等待输入)

  read -p "please input the data : " -t 5 test

  declare / typeset : 声明变量 ( 可以声明变量的类型 )  默认类型为字符串类型

    -a   变量为数组类型

    -i    变量为整数数字

    -x   声明为环境变量

    -r   readonly 类型 ( 不能被修改和 unset ) 如果要想改变,可以先改变变量的类型

    declare -i sum       sum=50+100 ( 注意不能有空格 )

    declare +i sum ( + 加号时取消的内容,即取消了sum是的数值属性,但是还是变量 )

   一维数组 :  declare -a var , var[1]=1 , var[2]=2,  var[3]=3 下标可以随便指定,如果不想要了这个数组可以整个取消 unset var ,也可以当个取消 unset var[2]

   declar -ia var; var[1]=1; echo ${var[1]}

限制系统的使用资源 ulimit

如果有10个用户登录,每个人用了100MB的内存,那么就是1G的内存,所以,可以通过此命令来限制每个用户使用资源的情况。主要是内存

ulimit [-SHacdfltu] 配额 -H 严格,-S 警告,-a显示所有设定,-c如果程序出错,将错误内容写成档案,-f 建立最大的shell档案,-d程序可使用的最大内存容量,-l可用于锁定内存 -t 可使用最大的CPU -u 单一用户可以使用的最大程序

最大档案一般被设定为2GB ( 我们服务器也是设定为 2GB )

ulimit -f 10240 表示设定了单个文件最大为 10M,此命令对管理数据库有一定用处。

 

变量的删除替换 :

例子 : /usr/kerberos/sbin: /usr/kerberos/bin: /usr/local/sbin: /usr/local/bin: /sbin:/bin:  ( \ 这其实是一行, 注意,方便查看我在每个冒号后边都加了 空格 )

/usr/sbin: usr/bin: /root/bin

将 kerberos 的删掉

注意:这种删掉, 计算机不知道分隔符之类的东西,所以,它是从左边开始找,找到匹配的字符就执行删除命令,例如 echo ${path#/*kerberos} 表示从左边第一个 / 开始执行,中间的 * 可以是任何字符,知道找到了第一个 kerberos 删除,所以只删除了第1个 kerberos字符,第2个 kerberos字符没有被删除,而且 /erberos/sbin: 后边的 /sbin还是会存在,如果是 echo ${path#/*kerberos/bin} , 一样, 会从左边第一个 /开始找到 第一个匹配的 kerberos/bin的执行,是一直找,从第一个,到该字符全部删除.

个人还是比较喜欢从左边开始,因为人类的顺序是从左到右

echo ${path/root/x} 将 root 换成 x

echo ${path//bin/x} 将所有的 bin 换成 x

  echo ${path#/*kerberos/bin:}                                     /*删除kerberos/bin , # 号的作用就是, #代表符合取代文字的最短的那一个, ##代表符合取代文字的最长的那一个 , %与%%的含义基本上与 #,##类似, 只是从后边开始算, $变量/旧字符串/新字符串( 若匹配, 则修改第一个 ) $变量//旧字符穿/新字符穿 若匹配则全部修改 */

  注意 此处的 { } 大括号是一定要有的 , * 可以是 任意多个字符

  替换 : echo{path/bin/Sbin} 就是将第一个bin替换成Sbin , echo{path//bin/Sbin} 将全部的bin替换成Sbin .

  有返回值的判断 : - 即首先判断变量内容,若不存在,则给一个值,若存在, 则继续使用存在的值, 例如 username={username-root} , 此含义为, 若username存在,则继续使用,若存在,则为root

  判断 : ? 只是测试变量是否存在 echo{patn?nopath} 如果path存在,则显示path内容, 若不存在, 则直接显示nopath

  以上有点类似sqlplus中修改 

  var=${str-expr}    var=${str:-expr} 加上冒号后的区别就是 str没有定义或者是空串时,var就等于后边的expr ( 跟没有冒号的区别就在空串的时候 )
  ( 还有几种方法,向后再说,个人感觉没啥用 )

 history : 查看输入过的命令

alias , unalias ( 起别名,和取消别名 )

指令的执行顺序 ( 即指令被搜索到的顺序 )

  1. 以相对或者绝对路径执行的命令 例如 /bin/ls    ./ls

  2. 以alias 找到该指令执行

  3. bash内建的命令执行

  4. 透过 $PATH 路径搜索到的指令执行

 进入画面 ( /etc/issue 主机登陆时 , /etc/motd 远程登陆时 )

 login shell , non-login sheill ( 一进入shell就有一大堆变量 )

  login shell : 是指输入用户名和密码 , 需要完整的登入流程. 例如 tty1 ~ tty6     读取文件 : /etc/profile , ~./bash_profile 或 ~/.bash_login ~/.profile
  由于以上两个文件 /etc/profile, ~/,bash_profile 都是取得login shell的时候才会读取的配置文件,所以如果你写入上述文件后,需要注销才能生效,可以使用命令 source 配置文件名, 例如source /etc/profile 就可以立刻生效。source 和. 一样。

 1. /etc/profile: 这是系统整体设定, 你最好不要修改这个档案, 这个档案还会去呼叫别的档案

 2. ~/.bash_profile 或 ~/.bash_login 属于使用者个人设定, 你要改自己的数据, 就写入这里

  non-login shell : 例如在一个 bash 中又输入 bash进入子程序, 此时没有输入用户名和密码, 子程序就是 non-login . 这种情况会读取 ~/.bashrc

 

环境设置

  登陆时可以是用 stty1 ~ stty6, 6个终端机登陆 linux , 其实也可以使用命令设置一些环境, 例如 在使用 sql plus 时, [Backspace] 并不是退格键, 此时, 我们可以使用命令, stty erase Backspace( 实际上键盘的退格键 ) , 就可以设置退格, 使用非常方便 . 还有一些别的设置方面的内容,  例如 stty -a 表示显示全部stty设置 .除此之外, 还可以使用 set进行设置.

终端机 stty1 ~ stty6 设置命令 stty, 例如 stty -a 显示全部设置 ( 可以设置经常使用的删除键 ) 另外 set 也可以设置

sqlplus 设置办法 stty erase ^H , 另外如果这样,下次启动的时候还是一样,所以。要修改 .bash_profile 加入stty erase ^H

 通配符 & 特殊字符

  * 代表 0 - 无穷多个字符

  ? 代表任一字符

  [ ] 代表其中一个字符 , 例如 [abcd]

  [ - ] 带表从多少到多少, 一般数字使用 ( 连续 ) [1-5] , 在编码顺序内的所有字符

  [ ^ ] 代表反向 例如 [^abc] 代表除了abc以外的任一字符(符合内容的全部)

  特殊符号 :

  # : 注释符号   最常用在script中

  \ : 逃脱符号   例如换到下一行继续输入命令啊,或者是转意等等

  | : 管线 ( 分割两个管线命令 )

  ; 连续命令 ( 不同于管线, 这两个命令是独立的 )   ls ; clear

  ~ 到家目录

  $ 变量符

  & 将指令变成背景下工作 ( 个人感觉是释放 bash , 例如输入 vi aaa & , 虽然打开了一个 vi, 但是光标还是在 bash 中,没有在 vi 中 )

  ! 逻辑运算非

  / 目录符号

  >,>> 数据流重定向 ( 输出导向 ) >取代 , >>累加

  <,<< 数据流重定向 ( 输入导向 )

  '' 单引号, 不具有变量置换功能

  "" 双引号, 具有变量置换功能

  `` 反引号, 在其中的命令先执行

  ( ) 子shell 开始与结束
  { } 命令区块组合

------------------------------------------------------------------------------------------------------------------------------------------------------

数据流重定向

数据流重定向 输出文件的规则 

1.该档案(~/rootfile)若不存在,系统会自动的将他建立起来,但是

2.当这个档案存在的时候,那么系统就会将这个档案内容清空,然后再将数据写入

3.也就是若以>输出到一个已存在的档案中,那个档案就会被覆盖掉。

4.>> 两个大于号可以实现累加数据,而不是覆盖数据。

标准输入 ( stdin ) : 代码为 0 , 使用 < 或 << ;

标准输出 ( stdout ) : 代码为 1, 使用 > 或 >>;

标准错误输出 ( stderr ) : 代码为 2, 使用 2> 或 2>> ; 

find /home aaa 1> asdf 2>bsdf

cat aaa.txt 1>bbb.txt 2>ccc.txt

/dev/null 黑洞目录,可以吃掉任何流向此目录的内容,一般是吃掉错误信息。

 

 就是将某个指令执行的本应该显示在屏幕上的结果的数据, 传输到了其他地方 . >

  < 将原本由键盘输入的内容, 改由其他档案取代.

  cat >filename <abc ( 从abc中读出数据, 并把数据显示在filename中)

  cat>filename<<"eof" ( 结束输入的字符 , 当输入eof时表示结束 ) 然后输入 this is a test 回车 , 继续 , 直到 eof 才能结束

  ls / > /rootfile        ( 屏幕上不会出现内容, 会将内容写入文件 rootfile , 如果rootfile不存在则会建立, 如果rootfile存在, 则会将文件清空,再将内容写入 )

  ls / >> /rootfile      ( 同上 , 只是如果文件存在不会清空文件中的内容, 只是将结果累加到文件中 )  ( 默认情况, 不用 1>, 1>> )

  错误情况 ls - 2> ( 2>> ) /rootfile   ( 错误的情况可以使用 2> , 2>> 将错误的内容写入文件 )

    例如 : find /home -name .bashrc > list_right 2>list_error                

  1> 默认 覆盖,写入

  1>> 接着写入

   2> 错误信息覆盖写入

   2>> 错误信息接着写入

   注意以上内容 , 数字与符号之间是没有空格的

     将两种信息写入一个文件时, find /home -name .bashrc >list_file 2>&1 ( & 的作用是变换背景 , 将 2> 变成 1> )

    同时写入时, 由于有可能写入方式是交替的, 这样就与之前想要写入的目的存在出入了, 所以此时需要使用特殊语法, 而并非只是单纯的写入而已, 使用的语法为2>&1 ,或者&>,例如 find /home -name .ba* &> list , 或者 find /home -name .ba* > list 2>&1

    < << 写入命令

    < : cat > abc.txt < x.txt ( 将 x.txt 中的内容读入 abc.txt , 此时的读入数据就来自 x.txt , 而不是屏幕输入的内容.( 也是覆盖的, 不是连接的 ) 此名录读作, 读入数据到abc.txt来自x.txt

    << : cat > abc.txt << "eof" ( 这个意思是, 可以输入内容, 直到读到 eof 结束, 也是覆盖内容 ) << 代表结束的输入字符

  多个指令 :

  ; 连续指令没有关系

  && || 多个指令相关 ( 用到指令传回 , 执行成功传回 0 , 否则传回 非 0 )

  cmd 1 && cmd2 ( 指令1执行正确, 则cmd2执行, 否则cmd2不执行) ( 要么都执行,要么都不执行)

  cmd 1 || cmd2 ( 指令1执行正确, 则cmd2不执行, 否则 com2 执行 ) ( 只能执行1个 )

  ls /tmp/abc || mkdir /tmp/abc ( 如果目录存在就显示, 否则就创建目录 )

  ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe ( 看来指令是从左到右执行的 )

  以上执行是否成功, 要确认执行命令的回传值, echo $? ( 变量问号, 就是上一次执行命令的回传值 ) , 回传值是0表示上一次命令正常执行

管线命令 :

管线命令使用 | 这个定界符,管线命令与连续下达命令是不一样的。 

ls -al /etc | less ,如此一来,使用ls指令输出后的内容,就能够被less读取,并且利用less功能 

  管线命令与普通的连接命令不一样 ; 普通连接命令,两个命令之间没有联系,而管线命令后一个命令要参考前一个命令的结果 ,管线命令的作用是, 当一个数据结果是需要经过几道命令完成的,这时候就需要使用管线命令,每个管线 | 后边必定是一个指令, 此指令接受上一个指令执行的结果,继续执行。例如 more , less 等等可以接收以上命令。

  管线命令只接收standard output , 会忽略 standard error output.

  管线命令必须是能够接受来自前一个指令的数据成为 standard input 继续处理才行.

截取命令 :

cut 与 grep :  echo $PATH | cut -d ':'  f 5  ( cut 是截取, 例如例子中用 : 截取 等等 , cut 的主要用途是将每一行里面的数据进行分解 )

cut 这个指令可以将一段讯息的某一段给切出来,处理单位是行

cut -d '分隔字符' -f fileds

-d 后边接分隔字符,跟- f 一起使用

-f 依据 -d 的分隔符将一段信息分割成为数段,用-f 取出第几段

-c 以字符为单位取出固定字符区间

echo $PATH | cut -d ":" -f 5

echo -c 5,10 /etc/passwd   只解决第5个和第10个字符(共两个 )

echo -c 5-10 /etc/passwd  解决第5个到第10个字符  ( 共六个 )

个人:感觉有点类似,有些文件格式很好,适合使用 cut 截取,比如有统一的分隔符号,等等 

 

grep : 分析一行的信息,有我们所需要的,就将改行拿出来

grep [-acinv] [--color=auto] '搜索的字符串' filename

-a : 将 binary 档案以 text 档案的方式搜寻数据

-c : 计算找到 '搜寻字符串'的次数

-i : 忽略大小写

-n : 顺便输出行号

-v : 反向选择,亦即显示出没有‘搜寻字符串’内容的哪一行

--color=auto 可以将找到的关键词部分加上颜色的显示

last | grep 'root'

ls | grep -c ( 注意,结果中,只显示次数,没有要显示的内容 )

ls | grep -i

ls | grep -n

ls | grep -v

 

排序命令 :

  sort 排序

sort [-fbMnrtuk] [file or stdin]

-f : 忽略大小写

-b : 忽略前边的空格

-M : 以月份的名字来排序

-n : 使用纯数字进行排序

-r : 反向排序

-u : 就是unique, 相同的数据中,进出现一行代表

-t : 分隔符,预设是用【tab】键分隔

-k : 以那个区间(filed)来进行排序

cat /etc/passwd | sort -t ':' -k 3 ( 含义是,用:来作为分隔符,另外以第3栏来进行排序 )

  uniq 去掉重复

 -i : 忽略大小写

-c : 进行计数

last | cut -d ' ' -f1 | sort | uniq ( 找到每一行中,去掉第一列重复的内容 )

  wc ( 输出行, 字数, 字符数 )

-l : 仅列出行

-w : 仅列出多少字

-m : 多少字符

cat /etc/man.confilg | wc   ( 输出结果为 141 722 4617  分别代表 行,字数,字符数 )

双向重导向 : ( 可以将结果保存到档案又输出到屏幕 ) tee

  ls -alF | tee filename | more  ( 输出到屏幕表示可以继续用管线重定向 )

-a : 以累加的方式,将数据加入 file 中.

字符转换命令 :

  tr : cat <filename | tr -d 'a'    

-d : 删除讯息当中的某个字符

-s : 取代掉重复的字符 ( 每一行取消连续的该字符,比如 aaa 最后就会 显示一个 a  )

last | tr '[a-z]' '[A-Z]' 将所有的小写字符变成大写字符

tr -d ':'  删除冒号 :

  col ( 个人感觉作用不大 )

-x : 表示将tab转换成空格, 

-b : 在文字内有反斜杠/时,仅保留反斜杠最后接的那个字符

cat /etc/man.config | col -x

col 会使输出的内容更加美观

  join 将两个档案有"相同数据"的行整和到同一行

-t : join默认以空格为分隔数据,并且比对第一个字段的数据 如果两个档案相同,则将两笔数据连成一行,且第一个字段放在第一个

-i : 忽略大小写

-1 : 代表第一个档案用哪个字段来分析

-2 : 代表第二个档案用哪个字段来分析

head -n 3 /etc/passwd /etc/shadow

可以发现,这两个档案的第一个字段是相同的,

join -t ':' /etc/shadow /etc/passwd

就将上述两个档案,在第一个字段相同的地方合并成同一行,并且只输出一份,因为合并成一份了

 

  paste 将两个档案的同一行粘贴在一起 ( 只是输出到标准输出,并不是真正的将两个档案合并 )

-d :后边接分隔符,预设是以【tab】来分隔的

- : 如果file 部分写成 - , 表示来自 standard input 的资料的意思

paste /etc/passwd /etc/shadow ( 注意输出结果,同一行是用【tab】来分隔的 )

  expand 将tab键转换成空格

-t : 后面可以接数字,一般来说 tab 键可以用 8 个空格键代替,也可以自行定义多少个空格取代 tab

head -n 3 /etc/passwd | expand

  split分割命令 将大的档案分割成小档案  cd /tmp ; split -b 300k /etc/tempcap tempcap ( 分割的档案会在最后的档安案名称中+ a,b等等 例如 tempcapa tempcapb )

split -[bl] file PREFIX

  - 使用  tar -cvf- /home | tar -cvf-( 最后的这个-实际是代表前面指令返回的结果 )

-b:后边可接欲分割成的档案的大小,可加单位,例如 b, k , m等

-l :以行数来进行分割

PREFIX :代表前导符的意思,可作为分割档案的前导文字 ( 所谓前导符,就是生成文件,前边都一样,一样的就是前导符,后边在不同,a,b...)

cd tmp; split  -b 300k /etc/termcap  termcap 这个就是前导符

命令执行后 : 得到的结果是,termcapa , termcapb, termcapc

参数代换 : xargs

产生某个指令的参数的意思。 xargs可以读入 stdin的数据,并且以空格符或断行字符作为分辨,将stdin的资料分隔成为 arguments。

xargs [-0epn] command

-0 :如果输入的 stdin中含有特殊字符,例如 \ ,空格等等,这个-0 可以将他们还原成一般字符。

-e :这个事 eof 的意思,后边接一个字符串,当 xargs 分析到这个字符时,就会停止工作

-p :在执行每个指令的 argument时,都会询问使用者的意思

-n :后面接次数,每次 command 指令执行时,要使用几个参数的意思。当 xargs没有接任何命令时,默认是以 echo来进行输出

cut -d':' -f1

减号 - 的用途

tar -cvf - /home | tar -xvf-

这个命令中,第二个 - 号表示,我不需要将文件输出到任何档案,而只把他作为 stdout 而最后的 - 则是取用前一个指令的 stdout

而最后一个表示,来自上一个 stdout 表示自己的 stdin 。
即 : stdin 和 stdout 可以利用减号 "-" 来替换。

 

   

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:135132次
    • 积分:2926
    • 等级:
    • 排名:第12544名
    • 原创:141篇
    • 转载:15篇
    • 译文:40篇
    • 评论:1条
    最新评论