理解shell(第五章)

1. shell的類型
 [root@localhost ~]# ls -l /bin/*sh
 -rwxr-xr-x. 1 root root 938832 Jul 18  2013 /bin/bash
 lrwxrwxrwx. 1 root root      4 Oct 27  2014 /bin/csh -> tcsh
 -rwxr-xr-x. 1 root root 109672 Oct 17  2012 /bin/dash
 lrwxrwxrwx. 1 root root      4 Oct 27  2014 /bin/sh -> bash
 -rwxr-xr-x. 1 root root 387328 Feb 22  2013 /bin/tcsh
 在centos6中運行上述命名可看到在centos中shell有bash、csh、dash。centos中終端默認啓動是一般爲bash。
    在命令行模式輸入bash命令,會生成一個子shell,使用exit命令退出子shell

2. shell的父子關係
 shell進程是存在父子關係的,父shell可以通過bash命令創建子shell、子shell還可以通過bash命令再次創建子shell,通過ps -f命令可以看到父子shell進程之間的關係,通過ps --forest 可以查看父子shell之間的 層級關係。當運行一個shell命令時,sehll會創建一個子來執行改命令

3. 進程列表
 當我們想一次運行多個命令時可以在命令與命令之間加上(;)這樣就shell就會依次執行這些命令。如下:
 [root@localhost ~]# pwd;ls;cd /etc
 /root
 anaconda-ks.cfg  Documents  install.log.syslog  Pictures  Templates
 Desktop          Downloads  Music               Public    Videos
 [root@localhost etc]#
 
 但上述並不是進程列表,將上述命令加到一個()裏,這樣就shell僅會生成一個子shell來執行這些命令,如下:
 [root@localhost ~]# (pwd;ls;cd /etc;pwd)
 /root
 anaconda-ks.cfg  Documents  install.log.syslog  Pictures  Templates
 Desktop          Downloads  Music               Public    Videos
 /etc
 
 還有一種創建進程列表的方法,它不會創建子shell進程,將命令放置於{}中,{}內首尾用空格隔開,命令後務必加(;),如下:
 [root@localhost ~]# { pwd;ls;cd /etc;pwd; }
 /root
 anaconda-ks.cfg  Documents  install.log.syslog  Pictures  Templates
 Desktop          Downloads  Music               Public    Videos
 /etc
 
 要知道是否生成了子進程可以使用$BASH_SUBSHELL環境變量的值來查看,爲0時表示沒有生成子進程,爲1時表示生成了子進程
 [root@localhost ~]# (pwd;ls;cd /etc;echo $BASH_SUBSHELL)
 /root
 anaconda-ks.cfg  Documents  install.log.syslog  Pictures  Templates
 Desktop          Downloads  Music               Public    Videos
 1
 
 [root@localhost ~]# { pwd;ls;cd /etc;echo $BASH_SUBSHELL; }
 /root
 anaconda-ks.cfg  Documents  install.log.syslog  Pictures  Templates
 Desktop          Downloads  Music               Public    Videos
 0
 
 使用子進程的開銷比較大,因爲終端控制着子進程的I/O
 
4. 後臺模式
 用終端啓動的進程一般會在前臺運行,通過下列方式可以將命令切至後臺運行
 COMMADN & :在命令後在&,可以將命令運行至後臺
 CTRL+Z:在命令運行時執行此操作可以將命令轉到後臺運行
 
 上述方法雖然將命令送至後臺運行但是依然與終端相關,如果需要剝離與終端的聯繫,應使用如下方式:
 nohub COMMAND &
 
 日常使用中可以使用後臺模式,讓命令執行時不受制於終端I/O,提高效率,例如進行文件歸檔時:
 $ (tar -cf Rich.tar /home/rich ; tar -cf My.tar /home/christine)&
 [3] 2423
 
 可以通過jobs命令來查看當前運行在後臺的進程,或jobs -l來查看更詳細的信息,一旦任務完成則會看到Done的提示
 還可以通過如下方式來控製作業
 fg [[%] JOB_NUM]:把指定的後臺作業調回前臺;
 bg [[%] JOB_NUM]:讓送回後臺的作業繼續運行;
 kill [[%] JOB_NUM]:終止指定作業
 
 可以用一個有意思的命令來查看後臺作業:
 sleep # & :讓進程睡眠#秒,此時可以使用jobs命令查看後臺作業
 
 協程命令coproc,它可以讓命令運行於後臺,可以創建一個子shell,然後在子shell中運行指定的命令,例如:
 [root@localhost etc]# coproc { sleep 10; }
 [1] 24343
 [root@localhost etc]# jobs -l
 [1]+ 24343 Running                 coproc COPROC { sleep 10; } &
 
5. 外部命令和內建命令
 可以通過type命令來區別外部命令和內建命令:
 [root@localhost etc]# type cd
 cd is a shell builtin
 [root@localhost etc]# type htop
 htop is /usr/bin/htop
 由上可以看出cd是一個內建命令,htop是一個外部命令,可以通過type -a來查看更詳細的信息,通過which命令來看到命令所在的路徑。
 
 有的命令存在外部和內建兩種方式,例如pwd:
 [root@localhost etc]# type -a pwd
 pwd is a shell builtin
 pwd is /bin/pwd
 [root@localhost etc]# which pwd
 /bin/pwd
 
 內建命令在運行時不會創建子進程來運行,比外部命令效率高。
 
 常用的內建命令有:
  history:用於管理命令歷史,當登錄shell時,會讀取命令歷史文件中的記錄,~/.bash_history,當退出shell會將登錄shell後執行的命令追加至命令歷史文件中。
  參數:
   -a:將當前shell中執行的命令追加到~/.bash_history中
   -d #:刪除指定編號的命令歷史中的命令
   -c:清空命令歷史
  快捷操作:
   !!:調用上一條命令
   !#:調用命令歷史中第#條命令
   ! string:調用命令歷史中最近一個以string開頭的命令
  
  alias/unalias:命令別名管理 
   alias 別名=命令名(如果包含空格需要在命令名外加引號):創建別名
   unalias 別名
   使用命令修改只能當前shell有效,如果要永久有小,需要修改~/.bashrc文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章