2013-05-14 31 views
5

Khi đọc manpage bash, .bashrc chỉ nên được thực thi khi trình bao chạy tương tác. Manpage định nghĩa tương tác như:Lệnh chạy qua ssh cũng chạy .bashrc?

Một vỏ tương tác là một bắt đầu không có đối số không lựa chọn và không có tùy chọn -c có chuẩn đầu vào và lỗi đều kết nối với thiết bị đầu cuối (như được xác định bởi isatty (3)) hoặc bắt đầu bằng tùy chọn -i. PS1 được đặt và $ - bao gồm i nếu bash là tương tác, cho phép tập lệnh shell hoặc tệp khởi động để kiểm tra trạng thái này.

Tuy nhiên, việc thực hiện lệnh bằng ssh cũng làm cho .bashrc được chạy, trái với những gì tôi mong đợi, do lệnh không chạy tương tác. Vì vậy, hành vi này có vẻ giống như một lỗi, nhưng nó cũng có vẻ phổ biến trên tất cả các phiên bản của Red Hat và bash mà tôi đã thử. Ai đó có thể giải thích tại sao hành vi này là chính xác?

Một điểm bổ sung: mặc dù .bashrc được chạy, $-$PS được đặt như thể trình bao không tương tác (như tôi mong đợi).

$ 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 

Tôi hiện đang làm việc xung quanh này bằng cách kiểm tra [[ $- = *i* ]] trong .bashrc, nhưng có vẻ như nếu tôi không cần phải làm điều đó.

Một ví dụ máy chủ, không chứa các file khác trong thư mục chính của tôi hơn .bashrc (và .ssh) có cấu hình này:

$ 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. 

Các phiên bản của bash mà tôi đã cố gắng này trên: 3.00.15, 3.1.17, 3.2.25, 4.1.2 (sau này trên Red Hat 6.3).

+0

Từ góc nhìn của máy từ xa, vỏ có lẽ là tương tác, mặc dù máy tính cục bộ không khiến người dùng tương tác. Bạn có thể kiểm tra các đối số dòng lệnh của shell từ xa không? –

+0

đầu ra của '.bash_profile' của bạn là gì? Tôi chỉ đang tìm một thứ như 'if [-f ~/.bashrc]; sau đó . ~/.bashrc fi' sẽ kích hoạt '.bashrc' khi đăng nhập. – Ewan

+0

@kisamoto: '.bash_profile' chỉ chạy cho một hệ vỏ đăng nhập. –

Trả lời

3

Từ Bash manual:

Bash cố gắng xác định khi nó đang được chạy với đầu vào tiêu chuẩn của nó kết nối với một kết nối mạng, như khi thực hiện bởi các daemon từ xa vỏ, thường rshd, hoặc daemon vỏ an toàn sshd. Nếu Bash xác định nó đang được chạy trong thời trang này, nó đọc và thực hiện các lệnh từ ~/.bashrc, nếu tệp đó tồn tại và có thể đọc được. Nó sẽ không làm điều này nếu được gọi là sh. Tùy chọn --norc có thể được sử dụng để ngăn chặn hành vi này và có thể sử dụng tùy chọn --rcfile để buộc một tệp khác được đọc, nhưng rshd thường không gọi trình bao với các tùy chọn đó hoặc cho phép chúng được chỉ định.

Cách giải quyết trong mặc định Debian bashrc xương là đặt sau ở đầu .bashrc:

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

Tôi thấy điều này trong manpage ngay bây giờ. Tôi đã nhầm lẫn bởi mô tả .bashrc đang được sử dụng cho các hệ vỏ tương tác: "~/.bashrc: Tệp khởi động mỗi lần tương tác riêng lẻ". –

Các vấn đề liên quan