• Shell及其操作环境


    来源:

    鸟哥的Linux私房菜第十章、認識與學習BASH

    Shell是什么?1分钟理解Shell的概念!

    ssh在本地调用远程主机上的命令,不登录远程主机shell

     一、Shell

    Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。

    Shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序,它和 QQ、迅雷、Firefox 等其它软件没有什么区别。然而 Shell 也有着它的特殊性,就是开机立马启动,并呈现在用户面前;用户通过 Shell 来使用 Linux,不启动 Shell 的话,用户就没办法使用 Linux。

    shell有两种意思 ,一种程序或一种脚本语言

    shell中可以执行shell脚本语言

    有的编程语言,如 C/C++、Pascal、汇编等,必须在程序运行之前将所有代码都翻译成二进制形式,也就是生成可执行文件,用户拿到的是最终生成的可执行文件,看不到源码。

    这个过程叫做编译(Compile),这样的编程语言叫做编译型语言,完成编译过程的软件叫做编译器(Compiler)。

    而有的编程语言,如 Shell、Python、PHP等,需要一边执行一边翻译,不会生成任何可执行文件,用户必须拿到源码才能运行程序。程序运行后会即时翻译,翻译完一部分执行一部分,不用等到所有代码都翻译完。

    这个过程叫做解释,这样的编程语言叫做解释型语言或者脚本语言(Script),完成解释过程的软件叫做解释器。

    编译型语言的优点是执行速度快、对硬件要求低、保密性好,适合开发操作系统、大型应用程序、数据库等。

    脚本语言的优点是使用灵活、部署容易、跨平台性好,非常适合 Web 开发以及小工具的制作。

    Shell 就是一种脚本语言,我们编写完源码后不用编译,直接运行源码即可,它的编译器(解释器)是 Shell 这个程序。

    其實殼程式的功能只是提供使用者操作系統的一個介面,因此這個殼程式需要可以呼叫其他軟體才好。 man, chmod, chown, vi, fdisk, mkfs 等等指令,這些指令都是獨立的應用程式, 但是我們可以透過殼程式 (就是指令列模式) 來操作這些應用程式,讓這些應用程式呼叫核心來運作所需的工作哩!也就是說,只要能夠操作應用程式的介面都能夠稱為殼程式。狹義的殼程式指的是指令列方面的軟體,包括本章要介紹的 bash 等。 廣義的殼程式則包括圖形介面的軟體!因為圖形介面其實也能夠操作各種應用程式來呼叫核心工作啊! windows下的powershell。

    二、linux中shell的种类

    centos6

    查看shell

    [root@node03 ~]# cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /bin/dash
    /bin/tcsh
    /bin/csh

    查看使用的shell

    [root@node03 ~]# echo $SHELL
    /bin/bash

    切换shell

    切换bash

    [root@node03 ~]# chsh -s /bin/bash
    Changing shell for root.
    Shell changed.

    切换的shell重新登录后生效

    Linux终极shell-zsh的完美配置方案!——oh-my-zsh

    雖然各家 shell 的功能都差不多,但是在某些語法的下達方面則有所不同,因此建議你還是得要選擇某一種 shell 來熟悉一下較佳。 Linux 預設就是使用 bash ,所以最初你只要學會 bash 就非常了不起了! ^_^! 另外,咦!為什麼我們系統上合法的 shell 要寫入 /etc/shells 這個檔案啊? 這是因為系統某些服務在運作過程中,會去檢查使用者能夠使用的 shells ,而這些 shell 的查詢就是藉由 /etc/shells 這個檔案囉!

    舉例來說,某些 FTP 網站會去檢查使用者的可用 shell ,而如果你不想要讓這些使用者使用 FTP 以外的主機資源時,可能會給予該使用者一些怪怪的 shell,讓使用者無法以其他服務登入主機。 這個時候,你就得將那些怪怪的 shell 寫到 /etc/shells 當中了。舉例來說,我們的 CentOS 7.x 的 /etc/shells 裡頭就有個 /sbin/nologin 檔案的存在,這個就是我們說的怪怪的 shell 囉~

    那麼,再想一想,我這個使用者什麼時候可以取得 shell 來工作呢?還有, 我這個使用者預設會取得哪一個 shell 啊?還記得我們在第四章的在終端介面登入linux小節當中提到的登入動作吧? 當我登入的時候,系統就會給我一個 shell 讓我來工作了。 而這個登入取得的 shell 就記錄在 /etc/passwd 這個檔案內!這個檔案的內容是啥?

    [dmtsai@study ~]$ cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    .....(底下省略).....

    如上所示,在每一行的最後一個資料,就是你登入後可以取得的預設的 shell 啦!那你也會看到, root 是 /bin/bash ,不過,系統帳號 bin 與 daemon 等等,就使用那個怪怪的 /sbin/nologin 囉~關於使用者這部分的內容,我們留在第十三章的帳號管理時提供更多的說明。

    三、Bash Shell 的操作環境

    我們在第五章第六章都曾談過『相對路徑與絕對路徑』的關係, 在本章的前幾小節也談到了 alias 與 bash 的內建命令。現在我們知道系統裡面其實有不少的 ls 指令, 或者是包括內建的 echo 指令,那麼來想一想,如果一個指令 (例如 ls) 被下達時, 到底是哪一個 ls 被拿來運作?很有趣吧!基本上,指令運作的順序可以這樣看:

    1. 以相對/絕對路徑執行指令,例如『 /bin/ls 』或『 ./ls 』;
    2. 由 alias 找到該指令來執行;
    3. 由 bash 內建的 (builtin) 指令來執行;
    4. 透過 $PATH 這個變數的順序搜尋到的第一個指令來執行。

    舉例來說,你可以下達 /bin/ls 及單純的 ls 看看,會發現使用 ls 有顏色但是 /bin/ls 則沒有顏色。 因為 /bin/ls 是直接取用該指令來下達,而 ls 會因為『 alias ls='ls --color=auto' 』這個命令別名而先使用! 如果想要瞭解指令搜尋的順序,其實透過 type -a ls 也可以查詢的到啦!上述的順序最好先瞭解喔!

    你是否會覺得奇怪,怎麼我們什麼動作都沒有進行,但是一進入 bash 就取得一堆有用的變數了? 這是因為系統有一些環境設定檔案的存在,讓 bash 在啟動時直接讀取這些設定檔,以規劃好 bash 的操作環境啦! 而這些設定檔又可以分為全體系統的設定檔以及使用者個人偏好設定檔。要注意的是, 我們前幾個小節談到的命令別名啦、自訂的變數啦,在你登出 bash 後就會失效,所以你想要保留你的設定, 就得要將這些設定寫入設定檔才行。底下就讓我們來聊聊吧!

    • login 與 non-login shell

    在開始介紹 bash 的設定檔前,我們一定要先知道的就是 login shell 與 non-login shell! 重點在於有沒有登入 (login) 啦!

    • login shell:取得 bash 時需要完整的登入流程的,就稱為 login shell。舉例來說,你要由 tty1 ~ tty6 登入,需要輸入使用者的帳號與密碼,此時取得的 bash 就稱為『 login shell 』囉;

    • non-login shell:取得 bash 介面的方法不需要重複登入的舉動,舉例來說,(1)你以 X window 登入 Linux 後, 再以 X 的圖形化介面啟動終端機,此時那個終端介面並沒有需要再次的輸入帳號與密碼,那個 bash 的環境就稱為 non-login shell了。(2)你在原本的 bash 環境下再次下達 bash 這個指令,同樣的也沒有輸入帳號密碼, 那第二個 bash (子程序) 也是 non-login shell 。

    為什麼要介紹 login, non-login shell 呢?這是因為這兩個取得 bash 的情況中,讀取的設定檔資料並不一樣所致。 由於我們需要登入系統,所以先談談 login shell 會讀取哪些設定檔?一般來說,login shell 其實只會讀取這兩個設定檔:

    1. /etc/profile:這是系統整體的設定,你最好不要修改這個檔案;
    2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:屬於使用者個人設定,你要改自己的資料,就寫入這裡!

    那麼,就讓我們來聊一聊這兩個檔案吧!這兩個檔案的內容可是非常繁複的喔!

    • /etc/profile (login shell 才會讀)

    你可以使用 vim 去閱讀一下這個檔案的內容。這個設定檔可以利用使用者的識別碼 (UID) 來決定很多重要的變數資料, 這也是每個使用者登入取得 bash 時一定會讀取的設定檔! 所以如果你想要幫所有使用者設定整體環境,那就是改這裡囉!不過,沒事還是不要隨便改這個檔案喔 這個檔案設定的變數主要有:

    • PATH:會依據 UID 決定 PATH 變數要不要含有 sbin 的系統指令目錄;
    • MAIL:依據帳號設定好使用者的 mailbox 到 /var/spool/mail/帳號名;
    • USER:根據使用者的帳號設定此一變數內容;
    • HOSTNAME:依據主機的 hostname 指令決定此一變數內容;
    • HISTSIZE:歷史命令記錄筆數。CentOS 7.x 設定為 1000 ;
    • umask:包括 root 預設為 022 而一般用戶為 002 等!

    /etc/profile 可不止會做這些事而已,他還會去呼叫外部的設定資料喔!在 CentOS 7.x 預設的情況下,底下這些資料會依序的被呼叫進來:

    • /etc/profile.d/*.sh

    其實這是個目錄內的眾多檔案!只要在 /etc/profile.d/ 這個目錄內且副檔名為 .sh ,另外,使用者能夠具有 r 的權限, 那麼該檔案就會被 /etc/profile 呼叫進來。在 CentOS 7.x 中,這個目錄底下的檔案規範了 bash 操作介面的顏色、 語系、ll 與 ls 指令的命令別名、vi 的命令別名、which 的命令別名等等。如果你需要幫所有使用者設定一些共用的命令別名時, 可以在這個目錄底下自行建立副檔名為 .sh 的檔案,並將所需要的資料寫入即可喔!

    • /etc/locale.conf

    這個檔案是由 /etc/profile.d/lang.sh 呼叫進來的!這也是我們決定 bash 預設使用何種語系的重要設定檔! 檔案裡最重要的就是 LANG/LC_ALL 這些個變數的設定啦!我們在前面的 locale 討論過這個檔案囉! 自行回去瞧瞧先!

    • /usr/share/bash-completion/completions/*

    記得我們上頭談過 [tab] 的妙用吧?除了命令補齊、檔名補齊之外,還可以進行指令的選項/參數補齊功能!那就是從這個目錄裡面找到相對應的指令來處理的! 其實這個目錄底下的內容是由 /etc/profile.d/bash_completion.sh 這個檔案載入的啦!

    反正你只要記得,bash 的 login shell 情況下所讀取的整體環境設定檔其實只有 /etc/profile,但是 /etc/profile 還會呼叫出其他的設定檔,所以讓我們的 bash 操作介面變的非常的友善啦! 接下來,讓我們來瞧瞧,那麼個人偏好的設定檔又是怎麼回事?

    • ~/.bash_profile (login shell 才會讀)

    bash 在讀完了整體環境設定的 /etc/profile 並藉此呼叫其他設定檔後,接下來則是會讀取使用者的個人設定檔。 在 login shell 的 bash 環境中,所讀取的個人偏好設定檔其實主要有三個,依序分別是:

    1. ~/.bash_profile
    2. ~/.bash_login
    3. ~/.profile

    其實 bash 的 login shell 設定只會讀取上面三個檔案的其中一個, 而讀取的順序則是依照上面的順序。也就是說,如果 ~/.bash_profile 存在,那麼其他兩個檔案不論有無存在,都不會被讀取。 如果 ~/.bash_profile 不存在才會去讀取 ~/.bash_login,而前兩者都不存在才會讀取 ~/.profile 的意思。 會有這麼多的檔案,其實是因應其他 shell 轉換過來的使用者的習慣而已。 先讓我們來看一下 dmtsai 的 /home/dmtsai/.bash_profile 的內容是怎樣呢?

    [dmtsai@study ~]$ cat ~/.bash_profile
    # .bash_profile
    
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then    <==底下這三行在判斷並讀取 ~/.bashrc
            . ~/.bashrc
    fi
    
    # User specific environment and startup programs
    PATH=$PATH:$HOME/.local/bin:$HOME/bin    <==底下這幾行在處理個人化設定
    export PATH

    這個檔案內有設定 PATH 這個變數喔!而且還使用了 export 將 PATH 變成環境變數呢! 由於 PATH 在 /etc/profile 當中已經設定過,所以在這裡就以累加的方式增加使用者家目錄下的 ~/bin/ 為額外的執行檔放置目錄。這也就是說,你可以將自己建立的執行檔放置到你自己家目錄下的 ~/bin/ 目錄啦! 那就可以直接執行該執行檔而不需要使用絕對/相對路徑來執行該檔案。

    這個檔案的內容比較有趣的地方在於 if ... then ... 那一段!那一段程式碼我們會在第十二章 shell script 談到,假設你現在是看不懂的。 該段的內容指的是『判斷家目錄下的 ~/.bashrc 存在否,若存在則讀入 ~/.bashrc 的設定』。 bash 設定檔的讀入方式比較有趣,主要是透過一個指令『 source 』來讀取的! 也就是說 ~/.bash_profile 其實會再呼叫 ~/.bashrc 的設定內容喔!最後,我們來看看整個 login shell 的讀取流程:

    login shell 的設定檔讀取流程
    圖10.4.1、login shell 的設定檔讀取流程

    實線的的方向是主線流程,虛線的方向則是被呼叫的設定檔!從上面我們也可以清楚的知道,在 CentOS 的 login shell 環境下,最終被讀取的設定檔是『 ~/.bashrc 』這個檔案喔!所以,你當然可以將自己的偏好設定寫入該檔案即可。 底下我們還要討論一下 source 與 ~/.bashrc 喔!

    • source :讀入環境設定檔的指令

    由於 /etc/profile 與 ~/.bash_profile 都是在取得 login shell 的時候才會讀取的設定檔,所以, 如果你將自己的偏好設定寫入上述的檔案後,通常都是得登出再登入後,該設定才會生效。那麼,能不能直接讀取設定檔而不登出登入呢? 可以的!那就得要利用 source 這個指令了!

    利用 source 或小數點 (.) 都可以將設定檔的內容讀進來目前的 shell 環境中! 舉例來說,我修改了 ~/.bashrc ,那麼不需要登出,立即以 source ~/.bashrc 就可以將剛剛最新設定的內容讀進來目前的環境中!很不錯吧!還有,包括 ~/bash_profile 以及 /etc/profile 的設定中, 很多時候也都是利用到這個 source (或小數點) 的功能喔!

    有沒有可能會使用到不同環境設定檔的時候?有啊! 最常發生在一個人的工作環境分為多種情況的時候了!舉個例子來說,在鳥哥的大型主機中, 常常需要負責兩到三個不同的案子,每個案子所需要處理的環境變數訂定並不相同, 那麼鳥哥就將這兩三個案子分別編寫屬於該案子的環境變數設定檔案,當需要該環境時,就直接『 source 變數檔 』,如此一來,環境變數的設定就變的更簡便而靈活了!

    • ~/.bashrc (non-login shell 會讀)

    談完了 login shell 後,那麼 non-login shell 這種非登入情況取得 bash 操作介面的環境設定檔又是什麼? 當你取得 non-login shell 時,該 bash 設定檔僅會讀取 ~/.bashrc 而已啦!那麼預設的 ~/.bashrc 內容是如何?

    [root@study ~]# cat ~/.bashrc
    # .bashrc
    
    # User specific aliases and functions
    alias rm='rm -i'             <==使用者的個人設定
    alias cp='cp -i'
    alias mv='mv -i'
    
    # Source global definitions
    if [ -f /etc/bashrc ]; then  <==整體的環境設定
            . /etc/bashrc
    fi

    特別注意一下,由於 root 的身份與一般使用者不同,鳥哥是以 root 的身份取得上述的資料, 如果是一般使用者的 ~/.bashrc 會有些許不同。看一下,你會發現在 root 的 ~/.bashrc 中其實已經規範了較為保險的命令別名了。 此外,咱們的 CentOS 7.x 還會主動的呼叫 /etc/bashrc 這個檔案喔!為什麼需要呼叫 /etc/bashrc 呢? 因為 /etc/bashrc 幫我們的 bash 定義出底下的資料:

    • 依據不同的 UID 規範出 umask 的值;
    • 依據不同的 UID 規範出提示字元 (就是 PS1 變數);
    • 呼叫 /etc/profile.d/*.sh 的設定

    你要注意的是,這個 /etc/bashrc 是 CentOS 特有的 (其實是 Red Hat 系統特有的),其他不同的 distributions 可能會放置在不同的檔名就是了。由於這個 ~/.bashrc 會呼叫 /etc/bashrc 及 /etc/profile.d/*.sh , 所以,萬一你沒有 ~/.bashrc (可能自己不小心將他刪除了),那麼你會發現你的 bash 提示字元可能會變成這個樣子:

    -bash-4.2$

    不要太擔心啦!這是正常的,因為你並沒有呼叫 /etc/bashrc 來規範 PS1 變數啦!而且這樣的情況也不會影響你的 bash 使用。 如果你想要將命令提示字元捉回來,那麼可以複製 /etc/skel/.bashrc 到你的家目錄,再修訂一下你所想要的內容, 並使用 source 去呼叫 ~/.bashrc ,那你的命令提示字元就會回來啦!

    四、ssh在本地调用远程主机上的命令,不登录远程主机shell

    需求描述

      在实际shell脚本的编写过程中,需要通过ssh远程执行一个命令,并返回执行的结果

      简单来说,就是将命令发送到远程的主机上进行执行,但是并没有实际的登录到远程主机上。即通过

      ssh的方式本地调用远程的命令。

    实现方法

      通过下面脚本测试通过ssh发送命令给远程主机,并且返回执行结果:

    ssh username@hostname command

    如果要发送多个命令,那么各个命令之间通过分号进行分隔。这个就是与在shell下一次执性多个命令一样的,用分号分隔开来。

    以交互式的方式执性远程命令

    通过在ssh命令中指定-t参数,就可以进行交互式的执行远程命令,简单来说,就是执行的命令需要远程主机的shell中的停留等待用户交互,即远程shell之间的交互,

    通过使用-t参数,ssh会保持一直登录到远程主机shell,直到退出交互命令。

    举例:

    未使用-t参数的top命令:

    [mysql@redhat6 ~]$ ssh oracle@standby top
    TERM environment variable not set

    使用-t参数的top命令:

    [mysql@redhat6 ~]$ ssh -t oracle@standby top
    top - 14:28:30 up  4:25,  3 users,  load average: 0.00, 0.00, 0.00
    Tasks:  92 total,   1 running,  91 sleeping,   0 stopped,   0 zombie
    Cpu(s):  0.1%us,  0.1%sy,  0.0%ni, 99.5%id,  0.2%wa,  0.0%hi,  0.0%si,  0.0%st
    Mem:   1922424k total,   223924k used,  1698500k free,    21528k buffers
    Swap:  3597144k total,        0k used,  3597144k free,    77832k cached
    
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                          
        1 root      20   0 19232 1500 1220 S  0.0  0.1   0:00.71 init                                                                                                                              
        2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                          
        3 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0                                                                                                                       
        4 root      20   0     0    0    0 S  0.0  0.0   0:00.01 ksoftirqd/0                                                                                                                       
                                                                                                                             
    Connection to standby closed.   #当通过Ctrl + C退出交互式命令时,就会断了与远程主机的连接。

    备注:通过以上的测试,使用-t选项,就是在发出命令之后,ssh还会保留在远程的shell上,等待命令执行完成或者说等待用户给出后续的命令,当用户发送

      退出交互命令之后,与远程的shell断开,回到本地的shell中

  • 相关阅读:
    手工创建数据库的全部脚本及说明(转)
    HNOI 2009 梦幻布丁 链表 启发式合并
    【除草】【hnoi】精简题解
    矩阵乘法
    忧桑啊。。。
    【水】【SCOI】 精简题解
    [数论][SDOI2012]Longge的问题
    【2013】省选
    【集训队互测】ayq 三道题
    【水】 【SDOI】 极精简题解
  • 原文地址:https://www.cnblogs.com/aidata/p/11745120.html
Copyright © 2020-2023  润新知