2013-05-14 167 views
5

在我閱讀bash manpage時,只應在shell以交互方式運行時執行.bashrc。手冊頁定義了交互爲:通過ssh運行命令也運行.bashrc?

一種交互式shell啓動一個沒有非選項參數 和不帶-c選項,其標準輸入和錯誤都 連接到端子(由isatty(3)確定) ,或者使用-i選項啓動 。 PS1被設置,$ - 包括我如果bash是 交互式,允許shell腳本或啓動文件來測試這個 狀態。

但是,使用ssh執行命令也會導致運行.bashrc,與我所期望的相反,因爲該命令不是交互式運行的。所以,這種行爲看起來像一個錯誤,但它似乎也廣泛應用於我試過的所有Red Hat和bash版本。有人能解釋爲什麼這種行爲是正確的嗎?

還有一點:即使運行.bashrc,$-$PS被設置爲好像shell是非交互式的(就像我期望的那樣)。

$ grep USER /etc/passwd 
USER:x:UID:GID:UNAME:/home/USER:/bin/bash 

$ cat ~/.bashrc 
echo bashrc:$-,$PS1 

$ bash -c 'echo $-' 
hBc 

$ ssh localhost 'echo $-' </dev/null 2>/dev/null 
[email protected]'s password: 
bashrc:hBc, 
hBc 

$ ssh localhost 'ps -ef | grep $$' </dev/null 2>/dev/null 
[email protected]'s password: 
bashrc:hBc, 
USER 28296 28295 0 10:04 ? 00:00:00 bash -c ps -ef | grep $$ 
USER 28297 28296 0 10:04 ? 00:00:00 ps -ef 
USER 28298 28296 0 10:04 ? 00:00:00 grep 28296 

我目前解決此工作由.bashrc中測試[[ $- = *i* ]],但它好像我不應該這樣做。

一個例子服務器,包含在我家目錄中沒有其他文件比的.bashrc(和的.ssh)有此配置:

$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.7 (Tikanga) 

$ bash --version 
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) 
Copyright (C) 2005 Free Software Foundation, Inc. 

的bash的版本,我已經試過這:3.00.15, 3.1.17,3.2.25,4.1.2(後者在Red Hat 6.3上)。

+0

從遠程計算機的角度來看,外殼或許是交互式的,即使在本地機器不會讓用戶交互。你能檢查遠程shell的命令行參數嗎? – 2013-05-14 15:34:27

+0

「.bash_profile」的輸出是什麼?我只是在尋找像'if [-f〜/ .bashrc];然後 。 〜/ .bashrc fi會在登錄時激活'.bashrc'。 – Ewan 2013-05-14 15:35:23

+0

@ kisamoto:'.bash_profile'僅對登錄shell運行。 – 2013-05-14 15:36:00

回答

3

Bash manual

擊嘗試確定何時它正在與它的連接到網絡連接,當由遠程外殼守護進程,通常rshd,或安全殼守護程序執行作爲標準輸入運行sshd。如果Bash確定它以這種方式運行,它將讀取並執行來自~/.bashrc的命令,如果該文件存在且可讀的話。如果作爲sh調用,它不會執行此操作。 --norc選項可用於禁止此行爲,而--rcfile選項可用於強制讀取其他文件,但rshd通常不會使用這些選項調用shell或允許指定它們。

Debian默認bashrc骨架的解決方法是將在.bashrc頂部以下內容:

# If not running interactively, don't do anything 
[ -z "$PS1" ] && return 
+0

我現在在手冊頁中看到了這一點。我對用於交互式shell的.bashrc描述感到困惑:「〜/ .bashrc:單個每個交互式shell啓動文件」。 – 2013-05-14 15:57:43