SSH遠程執行腳本報錯command not found和環境變量問題

SSH遠程執行腳本報錯command not found和環境變量問題

SSH遠程執行腳本報錯

SSH遠程執行腳本報錯"command not found",且環境變量不生效,執行env命令後發現打印出來的環境變量少了很多。

原因是之前將環境變量配置在了/etc/profile中,但是SSH遠程執行腳本時實際上執行的是non-login shell,而non-login shell不會讀取/etc/profile配置文件。

login shell和non-login shell

簡單來說,用SSH客戶端(比如Putty)登陸Linux系統時,要求輸入用戶名/密碼登錄或根據SSH key登錄時,就是login shell。

而在A機器上再用SSH免密碼登錄B機器,在B機器上執行Shell腳本,就是non-login shell。

ssh -o StrictHostKeyChecking=no -l root ${server} "~/test.sh"

用Ansible在目標機器上遠程執行Shell腳本時,也是non-login shell,因爲Ansible是基於SSH的。

Linux的環境配置文件

運行man bash可以查看環境配置文件的說明:

CentOS 7上的示例:

/etc/profile
       The systemwide initialization file, executed for login shells
/etc/bash.bash_logout
       The systemwide login shell cleanup file, executed when a login shell exits
~/.bash_profile
       The personal initialization file, executed for login shells
~/.bashrc
       The individual per-interactive-shell startup file
~/.bash_logout
       The individual login shell cleanup file, executed when a login shell exits
~/.inputrc
        Individual readline initialization file

補充說明:

Classically, ~/.profile is used by Bourne Shell, and is probably supported by Bash as a legacy measure. Again, ~/.login and ~/.cshrc were used by C Shell - I’m not sure that Bash uses them at all.

The ~/.bash_profile would be used once, at login. The ~/.bashrc script is read every time a shell is started. This is analogous to /.cshrc for C Shell.

One consequence is that stuff in ~/.bashrc should be as lightweight (minimal) as possible to reduce the overhead when starting a non-login shell.

I believe the ~/.environment file is a compatibility file for Korn Shell.

小結:

  • /etc 下的是系統環境配置,對所有用戶有效,但是/etc/profile只對login shell有效,而/etc/bashrc對login shell和non-login shell都有效。

  • ~下的是當前用戶環境配置,當前用戶環境配置會繼承·/etc系統環境配置。

login shell和non-login shell讀取的環境變量配置文件

login-shell讀取環境變量配置文件:

  • /etc/profile

  • ~/.bash_profile

  • ~/.profile

  • ~/.bashrc

  • /etc/bashrc

注意:~/.bash_profile中已經引入了~/.bashrc,而~/.bashrc引入了/etc/bashrc,因此login shell可以讀取到~/.bashrc/etc/bashrc的配置。

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

non-login shell讀取環境變量配置文件:

  • /etc/bashrc
  • ~/.bashrc

解決non-login shell的環境配置問題

方法一:

將login-shell和non-login shell都需要的環境配置放在~/.bashrc中,其它配置放在~/.bash_profile中。

方法二:

如果環境配置只放在~/.bash_profile中,需要執行non-login shell時先source ~/.bash_profile再執行命令。

Linux Shell Sebang的注意事項

雖然大多數情況下,在Shell開頭用#!/usr/bin/env bash#!/bin/bash更有通用性,但是在通過SSH遠程執行Shell腳本時,Shell開頭要用#!/bin/bash

參考文檔

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