Các tập lệnh trong /etc/profile.d Bị bỏ qua?


61

Tôi mới dùng Ubuntu. Tôi đang chạy máy tính để bàn 13.10.

Tôi muốn đặt một số bí danh trên toàn hệ thống và một dấu nhắc tùy chỉnh cho bash. Tôi tìm thấy bài viết này:

https://help.ubfox.com/community/En MôiVariables

Theo lời khuyên trong bài viết này, tôi đã tạo /etc/profiles.d/profile_local.sh. Nó được sở hữu bởi root và có quyền 644 giống như các tập lệnh khác ở đó:

root@ubuntu:/etc/profile.d# ll
total 28
drwxr-xr-x   2 root root  4096 Mar 23 08:56 .
drwxr-xr-x 135 root root 12288 Mar 23 09:15 ..
-rw-r--r--   1 root root   660 Oct 23  2012 bash_completion.sh
-rw-r--r--   1 root root  3317 Mar 23 07:36 profile_local.sh
-rw-r--r--   1 root root  1947 Nov 23 00:57 vte.sh

Tôi đã xác nhận thêm rằng / etc / hồ sơ gọi /etc/profile.d. Nó chứa khối mã này:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Khi đăng nhập, có vẻ như tập lệnh tùy chỉnh, profile_local.sh tôi đã tạo có nguồn gốc. Tuy nhiên, nếu sau khi đăng nhập, tôi 'source /etc.profile.d/profile_local.sh', tôi nhận được hành vi mong đợi, bí danh tùy chỉnh của mình và lời nhắc tùy chỉnh.

Tôi đang làm gì sai?

Nội dung của tập lệnh 'profile_local.sh':

# 3/23/14 - Copied from Gentoo /etc/bash/bashrc
# Placed in /etc/profile.d as described at:
# https://help.ubuntu.com/community/EnvironmentVariables

# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !


# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
        # Shell is non-interactive.  Be done now!
        return
fi

# Bash won't get SIGWINCH if another process is in the foreground.
# Enable checkwinsize so that bash will check the terminal size when
# it regains control.  #65623
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
shopt -s checkwinsize

# Enable history appending instead of overwriting.  #139609
shopt -s histappend

# Change the window title of X terminals 
case ${TERM} in
        xterm*|rxvt*|Eterm|aterm|kterm|gnome*|interix)
                PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                ;;
        screen)
                PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
                ;;
esac

use_color=false

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
        && type -P dircolors >/dev/null \
        && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
        # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
        if type -P dircolors >/dev/null ; then
                if [[ -f ~/.dir_colors ]] ; then
                        eval $(dircolors -b ~/.dir_colors)
                elif [[ -f /etc/DIR_COLORS ]] ; then
                        eval $(dircolors -b /etc/DIR_COLORS)
                fi
        fi

        if [[ ${EUID} == 0 ]] ; then
                PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
        else
                PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
        fi

        alias ls='ls --color=auto'
        alias grep='grep --colour=auto'
else
        if [[ ${EUID} == 0 ]] ; then
                # show root@ when we don't have colors
                PS1='\u@\h \W \$ '
        else
                PS1='\u@\h \w \$ '
        fi
fi

# Try to keep environment pollution down, EPA loves us.
unset use_color safe_term match_lhs

TZ="PST8PDT"

alias ll='ls -la'
alias dig='dig +search'
alias dir='ls -ba'

alias edit="ee"
alias ss="ps -aux"
alias dot='ls .[a-zA-Z0-9_]*'
alias news="xterm -g 80x45 -e trn -e -S1 -N &"

alias more="less"
alias c="clear"
alias m="more"
alias j="jobs"

# common misspellings
alias mroe=more
alias pdw=pwd

1
Không, nó không thể thực thi được nhưng cả hai kịch bản còn lại. Tuy nhiên tôi đã thay đổi nó và thử lại. Vẫn không có may mắn.
Drew

3
Điều này không liên quan gì đến việc thêm .sh, nó không liên quan và dù sao các tệp trong profile.dcó nguồn gốc, không được thực thi, hơi khác nhau và không yêu cầu tệp phải được thực thi. Vấn đề ở đây là profile& co không được đọc bởi các tập lệnh không đăng nhập.
terdon

1
Đã vẽ, đọc câu trả lời của tôi. Các tệp hồ sơ bị bỏ qua bởi các shell không đăng nhập nhưng đăng nhập GUI mặc định của Ubuntu sẽ đọc một số trong số chúng. Chỉ cần sử dụng .bashrcvà tất cả các vấn đề của bạn sẽ biến mất. Ngoài ra còn có một câu hỏi về quyền ưu tiên, nếu một trong các tệp được đọc sau đó cũng đặt PS1, thì giá trị trước đó sẽ bị loại bỏ. Dù sao, nghiêm túc, không chạm vào người quay phim /etc, chơi với những người trong thư mục nhà của bạn và .bashrckhông sử dụng hồ sơ.
terdon

1
Vâng, đó phải là một vỏ đăng nhập (đó là loại nếu điều bạn nên đưa vào câu hỏi của bạn vào lần tới). Tuy nhiên, hầu hết các hệ thống đều có .profilecác tệp mặc định trong nhà của bạn và các cài đặt ở đó sẽ ghi đè lên mọi thứ bạn làm /etc/profile. Về cơ bản không bao giờ chạm vào /etctrừ khi bạn biết những gì bạn đang làm. Đó là những gì các tập tin người dùng dành cho. Ngoài ra, vui lòng chỉnh sửa câu hỏi của bạn và giải thích chính xác cách bạn đang kết nối, điều đó thay đổi mọi thứ.
terdon

4
Vui lòng không làm điều này bằng cách sử dụng /etc/profile.dđó là một ý tưởng thực sự tồi tệ và sẽ ảnh hưởng đến tất cả người dùng hệ thống. Chỉ cần bao gồm các lệnh từ profile_local.shtrong ~/.profilehoặc đơn giản là nguồn kịch bản bằng cách thêm dòng này vào ~/.profile: . /path/to/profile_local.sh. ( .phương tiện source, nó sẽ đọc tệp bạn cung cấp cho nó và chạy các lệnh nó tìm thấy ở đó).
terdon

Câu trả lời:


109

Để hiểu những gì đang diễn ra ở đây, bạn cần hiểu một chút thông tin cơ bản về cách shell (bash trong trường hợp này) được chạy.

  • Khi bạn mở một trình giả lập thiết bị đầu cuối ( gnome-terminalví dụ), bạn đang thực thi cái được gọi là shell tương tác, không đăng nhập .

  • Khi bạn đăng nhập vào máy của mình từ dòng lệnh, thông qua sshhoặc chạy một lệnh như su - username, bạn đang chạy một vỏ đăng nhập tương tác .

  • Khi bạn đăng nhập bằng đồ họa, bạn đang chạy một cái gì đó hoàn toàn khác, các chi tiết sẽ phụ thuộc vào hệ thống và môi trường đồ họa của bạn, nhưng nói chung nó là vỏ đồ họa liên quan đến đăng nhập của bạn. Trong khi nhiều shell đồ họa (bao gồm mặc định Ubuntu) sẽ đọc /etc/profilekhông phải tất cả chúng đều làm được.

  • Cuối cùng, khi bạn chạy một kịch bản shell, nó được chạy trong một vỏ không tương tác, không đăng nhập .

Bây giờ, các tệp bash sẽ đọc khi được khởi chạy tùy thuộc vào loại vỏ mà nó đang chạy. Sau đây là đoạn trích của phần man bashHÓA ĐƠN của (phần nhấn mạnh của tôi):

Khi bash được gọi dưới dạng shell đăng nhập tương tác hoặc dưới dạng shell không tương tác với tùy chọn --login, trước tiên, nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile , nếu tệp đó tồn tại. Sau khi đọc tệp đó, nó tìm ~ / .bash_profile, ~ / .bash_login và ~ / .profile, theo thứ tự đó , đọc và thực thi các lệnh từ lệnh đầu tiên tồn tại và có thể đọc được. Tùy chọn --noprofile có thể được sử dụng khi trình bao bắt đầu ngăn chặn hành vi này.

Khi một vỏ tương tác đó là không phải là một vỏ đăng nhập được khởi động, bash đọc và thực hiện lệnh từ /etc/bash.bashrc~ / .bashrc , nếu những tập tin này tồn tại. Điều này có thể bị ức chế bằng cách sử dụng tùy chọn --norc. Tùy chọn tệp --rcfile sẽ buộc bash đọc và thực thi các lệnh từ tệp thay vì /etc/bash.bashrc và ~ / .bashrc.

Tất cả điều này có nghĩa là bạn đang chỉnh sửa tệp sai. Bạn có thể kiểm tra điều này bằng cách thả vào bảng điều khiển ảo bằng cách sử dụng Ctrl+ Alt+ F2(quay lại GUI bằng Alt+ F7hoặc F8tùy thuộc vào thiết lập của bạn) và đăng nhập vào đó. Bạn sẽ thấy rằng dấu nhắc và bí danh của bạn có sẵn.

Vì vậy, để áp dụng cài đặt bạn muốn áp dụng cho các shell không đăng nhập, loại bạn nhận được mỗi khi bạn mở một thiết bị đầu cuối, bạn nên thay đổi ~/.bashrcthay thế. Ngoài ra, bạn cũng có thể đặt bí danh của mình trong tệp ~/.bash_aliases(tuy nhiên, lưu ý rằng đây là một tính năng của Ubuntu và bạn không nên mong đợi nó hoạt động trên các bản phân phối khác).

Để biết thêm chi tiết về tập tin nào sẽ được sử dụng cho mục đích gì, xem tại đây .


GHI CHÚ:

  • Debian (và bởi phần mở rộng Ubuntu) cũng có ~/.profilenguồn mặc định ~/.bashrc. Điều này có nghĩa là bất kỳ thay đổi nào bạn thực hiện ~/.bashrccũng sẽ được kế thừa bởi các shell đăng nhập nhưng tôi) đây không phải là trường hợp trong tất cả các máy Linux / Unix và ii) điều ngược lại là không đúng, đó là lý do tại sao bạn nên luôn luôn làm việc với ~/.bashrc& co thay vì ~/.profilehoặc /etc/profile.

  • Ngoài ra, một lưu ý chung về việc sử dụng, những thay đổi được thực hiện đối với các tệp cấu hình trong /etcsẽ ảnh hưởng đến tất cả người dùng. Đây thường không phải là những gì bạn muốn làm và nên tránh. Bạn phải luôn luôn sử dụng các tệp tương đương trong thư mục chính của bạn ( ~/).

  • Các tập tin cấu hình khác nhau được đọc tuần tự. Cụ thể, đối với shell đăng nhập, thứ tự là:

    /etc/profile -> /etc/profile.d/* (in alphabetical order) -> ~/.profile

    Điều này có nghĩa là mọi cài đặt trong ~/.profilesẽ ghi đè lên mọi thứ được đặt trong các tệp trước đó.


1
Theo bài đăng này howtolamp.com/articles/ , bạn cũng có thể chạy echo $0từ một thiết bị đầu cuối và nếu đầu ra có tiền tố là "-" thì bạn đang ở trong vỏ đăng nhập.
stackoverflower

@stackoverflower không có trên hệ thống của tôi. Điều đó làm việc cho một vỏ đăng nhập tương tác từ xa. Có vẻ như không chạy bash -l. Trong mọi trường hợp, tại sao điều đó có liên quan? Câu hỏi không phải là về cách kiểm tra loại vỏ bạn đang chạy.
terdon

bài đăng tuyệt vời, tự hỏi tại sao nó không xuất hiện trên google khi tôi gặp vấn đề tương tự
Donato

@stackoverflower Nếu "$0"mở rộng sang một cái gì đó bắt đầu bằng -, thì bạn biết bạn có một vỏ đăng nhập. Nhưng điều ngược lại là không đúng: sự vắng mặt của -không đảm bảo bạn không ở trong vỏ đăng nhập. Hầu hết các cách phổ biến để bắt đầu đăng nhập shell cung cấp cho bạn một hàng đầu -, nhưng không phải tất cả. man bashcho chúng tôi biết "Một vỏ đăng nhập là một cái mà ký tự đầu tiên của đối số 0 là một -hoặc một bắt đầu với --logintùy chọn." ( -llà dạng ngắn của --login; chúng tương đương .) Trong Bash bạn có thể chạy shopt login_shellđể kiểm tra.
Eliah Kagan

2

Một khả năng khác, đặc biệt đối với các thiết lập như các thiết lập lịch sử HISTSIZE, HISTFILESIZE, HISTCONTROL, và PS1là các tập tin đang được tải, nhưng các thiết lập sẽ bị ghi đè trong một tập tin đó là nguồn sau, với nguyên nhân chủ yếu là ~/.bashrc. (Tôi có một bộ cài đặt mặc định cho các máy chủ của chúng tôi, như lời nhắc có màu đỏ để root để cảnh báo người dùng và lịch sử lớn với dấu thời gian)

Ubuntu mặc định .bashrctừ /etc/skelmột số cài đặt, có thể có ý nghĩa được đặt từ một nơi nào đó sẽ không ghi đè cài đặt do chủ sở hữu hệ thống đặt từ /etc/profile.d(Thích /etc/bash.bashrc) (Nếu người dùng chỉnh sửa .bashrc, sẽ ghi đè cài đặt, các tệp mặc định của hệ thống khó chịu hơn)


2

trong phiên Debian cho Terminal tôi đã giải quyết vấn đề này cho tất cả người dùng:

thêm vào

sudo nano /etc/bash.bashrc

khối

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

từ

/etc/profile

1

Theo con đường này:

  • Mở Chỉnh sửa -> Tùy chọn
  • Trong tab đầu tiên "Chung", dưới nhãn "Lệnh", bật "Chạy lệnh dưới dạng vỏ đăng nhập"

-1

PHIÊN BẢN = "16.04.3 LTS (Xenial Xerus)"

Được rồi vì vậy mọi người đều cho rằng người ở đây không muốn /etc/profile.d/somefile.sh cho tất cả người dùng, nhưng trong trường hợp của tôi đó chính xác là những gì tôi muốn.

Vì vậy, thực sự như với Ubuntu nếu bạn sử dụng nó và bạn muốn nó có hiệu lực trong vỏ đồ họa của bạn, tất cả những gì bạn phải làm là đặt tệp và sau đó đăng xuất và đăng nhập lại. Tất cả các bảng điều khiển của bạn hoặc bất cứ thứ gì bạn khởi chạy cho dù đó là loại xterm hoặc loại bảng điều khiển (Hoặc thả vào trình bao) bây giờ sẽ có tệp đó có nguồn gốc.

Không cần sử dụng .bashrc, vv cho tất cả người dùng. Xin lỗi điều này chỉ không rõ ràng trong câu trả lời ở trên. Tất cả những gì họ nói là đúng nhưng thực tế thì hầu như không đúng vì mọi thứ mà trình quản lý windows khởi chạy sẽ kế thừa các cài đặt này, vì vậy chỉ cần đăng nhập lại và giải quyết vấn đề của bạn và đừng bận tâm với .bashrc, v.v. nếu ý định của bạn là áp dụng nó cho tất cả người dùng .


2
Vấn đề của tôi là chính xác rằng điều này không xảy ra trong thiết bị đầu cuối chạy dưới giao diện người dùng đồ họa; không có trong Ubuntu 16.04.3 hoặc 18.04.
Thomas Arildsen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.