shell打开wifi命令_远程执行命令的填坑记录
前言
本文主要記錄 bash 四種模式的細節,以便于遇到問題時查閱。
遠程執行出錯了
最近使用 ansible 比較多,在某次使用 shell 模塊遠程執行命令的時候老是報 ‘command not found’。
但是手動登錄到遠端機器執行命令是成功的,于是開始思考里面的細節。
特別感謝這篇博文
bash 的四種模式
遇到問題的時候就覺得應該是環境變量的關系。
因為使用的是 bash,那下面就來記錄一下 bash 的細節。
1. interactive + login shell
第一種是交互式的登錄 shell。
這里需要理解兩個概念:interactive , login。
login shell 指用戶以非圖形界面或者以 ssh 登錄到機器上時獲得的第一個 shell 。
- 簡單些說就是需要輸入用戶名和密碼的 shell
- 通常不管以何種方式登錄機器后用戶獲得的第一個 shell 就是 login shell。
interactive shell 會有一個輸入提示符,并且它的標準輸入、輸出和錯誤輸出都會顯示在控制臺上。
- 一般來說只要是需要用戶交互的,即一個命令一個命令輸入的 shell 都是 interactive shell。
- 如果無需用戶交互,它便是 non-interactive shell。
- 通常來說如bash script.sh此類執行腳本的命令就會啟動一個 non-interactive shell,它不需要與用戶進行交互,執行完后它便會退出創建的 shell。
那么這個模式下最簡單的兩個例子就是:
- 用戶直接登錄到機器獲得的第一個 shell
- 用戶使用ssh user@remote獲得的 shell
這種模式下,shell 首先加載/etc/profile,然后再嘗試依次去加載下列三個配置文件之一,一旦找到其中一個便不再接著尋找:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
2. non-interactive + login shell
第二種模式的 shell 為 non-interactive login shell,即非交互式的登錄 shell,這種是不太常見的情況。
一種創建此 shell 的方法為:bash -l script.sh,-l 參數是將 shell 作為一個 login shell 啟動,而執行腳本又使它為 non-interactive shell。
對于這種類型的 shell,配置文件的加載與第一種完全一樣。
3. interactive + non-login shell
第三種模式為交互式的非登錄 shell。
這種模式最常見的情況是在一個已有 shell 中運行 bash,此時會打開一個交互式的 shell,而因為不再需要登錄,因此不是 login shell。
對于此種情況,啟動 shell 時會去查找并加載 /etc/bash.bashrc 和 ~/.bashrc 文件。
bashrc vs profile
- profile 類型文件,它是某個用戶唯一的用來設置全局環境變量的地方 。
因為用戶可以有多個 shell 比如 bash, sh, zsh 等, 但像環境變量這種其實只需要在統一的一個地方初始化就可以了, 而這個地方就是 profile。
所以啟動一個 login shell 會加載此文件,后面由此 shell 中啟動的新 shell 進程如 bash,sh,zsh 等都可以由 login shell 中 繼承環境變量等配置。 - bashrc,其后綴 rc 的意思為 Run Commands,由名字可以推斷出,此處存放 bash 需要運行的命令 。
但注意,這些命令一般只用于交互式的 shell,通常在這里會設置交互所需要的所有信息,比如 bash 的補全、alias、顏色、提示符等等。
所以引入多種配置文件完全是為了更好的管理配置,每個文件各司其職,只做好自己的事情。
4. non-interactive + non-login shell
最后一種模式為非交互非登錄的 shell,創建這種 shell 典型有兩種方式:
- bash script.sh
- ssh user@remote command
這兩種都是創建一個 shell,執行完腳本之后便退出,不再需要與用戶交互。
對于這種模式而言,它會去尋找環境變量BASH_ENV,將變量的值作為文件名進行查找,如果找到便加載它。
典型模式總結
下面舉一些例子:
- 登錄機器后的第一個 shell:login + interactive
- 新啟動一個 shell 進程,如運行 bash:non-login + interactive
- 執行腳本,如bash script.sh:non-login + non-interactive
- 運行頭部有如#!/usr/bin/env bash的可執行文件,如./executable:non-login + non-interactive
- 通過 ssh 登錄到遠程主機:login + interactive
- 遠程執行腳本,如ssh user@remote script.sh:non-login + non-interactive
- 遠程執行腳本,同時請求控制臺,如ssh user@remote -t 'echo $PWD':non-login + interactive
- 在圖形化界面中打開 terminal:Linux 上 : non-login + interactive;Mac OS X 上 : login + interactive
有出路了
通過上面的總結,ansible 的 shell 模塊遠程執行命令應該就是屬于 non-login + non-interactive。
對于這種模式,bash 會選擇加載$BASH_ENV的值對應的文件。
但是,注意到命令里面的那個腳本的第一行#!/usr/bin/env sh,并不是 bash,而是 sh。
那么 bash 和 sh 有啥區別呢?
通過執行whereis命令查看發現,sh 只是 bash 的一個軟鏈接。
再通過查看文檔知道,當 bash 以 sh 命令啟動時,bash 會盡可能的模仿 sh。
所以配置文件的加載變成了下面這樣:
- interactive + login : 讀取 /etc/profile 和 ~/.profile
- non-interactive + login : 同上
- interactive + non-l gin : 讀取 ENV 環境變量對應的文件
- non-interactive + non-login : 不讀取任何文件
所以如果是 sh 的話,不會加載任何環境變量,結果還是 command not found。
最后的解決辦法就是:
- 第一步 設置$BASH_ENV為/etc/profile
- 第二步 將#!/usr/bin/env sh改成#!/usr/bin/env bash
參考
ssh連接遠程主機執行腳本的環境變量問題?feihu.me 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的shell打开wifi命令_远程执行命令的填坑记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 获取对话框对象,Andr
- 下一篇: elasticsearch group