Script di /etc/profile.d Diabaikan?

61

Saya baru di Ubuntu. Saya menjalankan 13.10 Desktop.

Saya ingin menetapkan beberapa alias sistem lebar dan prompt kustom untuk bash. Saya menemukan artikel ini:

https://help.ubuntu.com/community/EnvironmentVariables

Mengikuti saran dalam artikel ini, saya membuat /etc/profiles.d/profile_local.sh. Itu dimiliki oleh root dan memiliki izin 644 seperti skrip lain di sana:

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

Saya telah mengkonfirmasi lebih lanjut bahwa / etc / profile calls /etc/profile.d. Ini mengandung blok kode ini:

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

Setelah masuk, tampaknya skrip khusus, profile_local.sh yang saya buat tidak bersumber. Namun jika setelah login saya 'source /etc.profile.d/profile_local.sh', saya mendapatkan perilaku yang diharapkan, alias kustom saya, dan custom prompt.

Apa yang saya lakukan salah?

Isi skrip '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
Drew
sumber
1
Tidak, ini tidak dapat dieksekusi tetapi juga dua skrip lainnya. Namun saya mengubahnya dan mencoba lagi. Masih belum berhasil.
Drew
3
Ini tidak ada hubungannya dengan menambahkan .sh, itu tidak relevan dan lagi pula file dalam profile.dbersumber, tidak dieksekusi yang sedikit berbeda dan tidak memerlukan file untuk dapat dieksekusi. Masalahnya di sini adalah bahwa profile& co tidak dibaca oleh skrip non-login.
terdon
1
Drew, baca jawabanku. File profil diabaikan oleh shell non-login tetapi login GUI default Ubuntu akan membacanya. Cukup gunakan .bashrcdan semua masalah Anda akan hilang. Ada juga pertanyaan tentang diutamakan, jika salah satu file yang dibaca kemudian juga menetapkan PS1, maka nilai sebelumnya akan dibuang. Ngomong-ngomong, serius, jangan menyentuh filer di /etc, bermain dengan yang di dir rumah Anda dan menggunakan .bashrcbukan profil.
terdon
1
Ya, itu harus menjadi shell login (itu adalah jenis jika hal yang harus Anda sertakan dalam pertanyaan Anda waktu berikutnya). Namun, sebagian besar sistem memiliki .profilefile default di rumah Anda dan pengaturan di sana akan menimpa apa pun yang Anda lakukan /etc/profile. Pada dasarnya jangan pernah menyentuh /etckecuali Anda tahu apa yang Anda lakukan. Untuk itulah file khusus pengguna. Juga, harap edit pertanyaan Anda dan jelaskan bagaimana Anda terhubung, yang mengubah segalanya.
terdon
4
Tolong jangan lakukan ini menggunakan /etc/profile.ditu adalah ide yang sangat buruk dan akan mempengaruhi semua pengguna sistem. Hanya menyertakan perintah dari profile_local.shdalam Anda ~/.profileatau hanya sumber script dengan menambahkan baris ini ke Anda ~/.profile: . /path/to/profile_local.sh. ( .Berarti source, itu akan membaca file yang Anda berikan dan menjalankan perintah yang ditemukannya di sana).
terdon

Jawaban:

109

Untuk memahami apa yang terjadi di sini, Anda perlu memahami sedikit informasi latar belakang tentang bagaimana cangkang (bash dalam kasus ini) dijalankan.

  • Ketika Anda membuka terminal emulator ( gnome-terminalmisalnya), Anda mengeksekusi apa yang dikenal sebagai shell non-login yang interaktif .

  • Ketika Anda masuk ke mesin Anda dari baris perintah, melalui ssh, atau menjalankan perintah seperti su - username, Anda menjalankan shell login interaktif .

  • Ketika Anda login secara grafis, Anda menjalankan sesuatu yang sama sekali berbeda, detailnya akan tergantung pada sistem dan lingkungan grafis Anda, tetapi secara umum itu adalah shell grafis yang berhubungan dengan login Anda. Sementara banyak shell grafis (termasuk default Ubuntu) akan membaca /etc/profiletidak semuanya.

  • Akhirnya, ketika Anda menjalankan skrip shell, dijalankan di shell non-interaktif, non-login .

Sekarang, file yang akan dibaca bash saat diluncurkan tergantung pada jenis shell yang dijalankannya. Berikut ini adalah kutipan dari bagian INVOCATION dari man bash(penekanan tambang):

Ketika bash dipanggil sebagai shell login interaktif , atau sebagai shell non-interaktif dengan opsi --login, ia pertama kali membaca dan mengeksekusi perintah dari file / etc / profile , jika file itu ada. Setelah membaca file itu, ia mencari ~ / .bash_profile, ~ / .bash_login, dan ~ / .profile, dalam urutan itu , dan membaca serta mengeksekusi perintah dari yang pertama yang ada dan dapat dibaca. Opsi --noprofile dapat digunakan ketika shell mulai menghambat perilaku ini.

Ketika shell interaktif yang bukan shell login dimulai, bash membaca dan mengeksekusi perintah dari /etc/bash.bashrc dan ~ / .bashrc , jika file-file ini ada. Ini dapat dihambat dengan menggunakan opsi --norc. Opsi file --rcfile akan memaksa bash untuk membaca dan menjalankan perintah dari file alih-alih /etc/bash.bashrc dan ~ / .bashrc.

Artinya semua ini adalah Anda mengedit file yang salah. Anda dapat menguji ini dengan menjatuhkan ke konsol virtual menggunakan Ctrl+ Alt+ F2(kembali ke GUI dengan Alt+ F7, atau F8tergantung pada pengaturan Anda) dan masuk di sana. Anda akan melihat bahwa prompt dan alias Anda tersedia.

Jadi, agar pengaturan yang Anda inginkan diterapkan pada shell non-login, tipe yang Anda dapatkan setiap kali Anda membuka terminal, Anda harus melakukan perubahan ~/.bashrc. Sebagai alternatif, Anda juga dapat menempatkan alias di dalam file tersebut ~/.bash_aliases(namun, perhatikan bahwa ini adalah fitur Ubuntu dan Anda seharusnya tidak mengharapkannya berfungsi pada distribusi lain).

Untuk detail lebih lanjut tentang file mana yang harus digunakan untuk apa, lihat di sini .


CATATAN:

  • Debian (dan dengan ekstensi Ubuntu) juga memiliki ~/.profilesumber default ~/.bashrc. Ini berarti bahwa setiap perubahan yang Anda buat ~/.bashrcjuga akan diwarisi oleh shell login tetapi i) ini tidak terjadi di semua mesin Linux / Unix dan ii) kebalikannya tidak benar yang mengapa Anda harus selalu bekerja dengan ~/.bashrc& co daripada ~/.profileatau /etc/profile.

  • Juga, catatan umum tentang penggunaan, perubahan yang dilakukan pada file konfigurasi /etcakan mempengaruhi semua pengguna. Ini biasanya bukan yang ingin Anda lakukan dan harus dihindari. Anda harus selalu menggunakan file yang setara di direktori home Anda ( ~/).

  • Berbagai file konfigurasi dibaca secara berurutan. Khususnya, untuk shell login, urutannya adalah:

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

    Ini berarti bahwa pengaturan apa pun di ~/.profileakan menimpa apa pun yang diatur dalam file sebelumnya.

terdon
sumber
1
Menurut postingan ini howtolamp.com/articles/… , Anda juga dapat menjalankan echo $0dari terminal dan jika output diawali dengan "-" maka Anda berada dalam shell login.
stackoverflower
@stackoverflower tidak ada di sistem saya. Itu berfungsi untuk shell login interaktif jarak jauh. Sepertinya tidak ketika berjalan bash -l. Bagaimanapun, mengapa itu relevan? Pertanyaannya bukan tentang bagaimana memeriksa jenis shell yang Anda jalankan.
terdon
posting magnificant, bertanya-tanya mengapa itu tidak muncul di google ketika saya memiliki masalah yang sama
Donato
@stackoverflower Jika "$0"memperluas ke sesuatu yang dimulai dengan -, maka Anda tahu Anda memiliki shell login. Tetapi kebalikannya tidak benar: tidak adanya -tidak memastikan Anda tidak berada di shell login. Cara paling umum memulai shell login memang memberi Anda petunjuk -, tetapi tidak semua. man bashmemberitahu kita " Shell login adalah karakter dengan argumen pertama nol adalah -, atau yang dimulai dengan --loginopsi." ( -ladalah bentuk pendek dari --login; mereka setara .) Di Bash Anda dapat menjalankan shopt login_shelluntuk memeriksa.
Eliah Kagan
2

Kemungkinan lain, terutama untuk pengaturan seperti pengaturan sejarah HISTSIZE, HISTFILESIZE, HISTCONTROL, dan PS1adalah bahwa file sedang dimuat, tetapi pengaturan ditimpa dalam file lain yang sumber kemudian, dengan penyebab yang paling mungkin menjadi ~/.bashrc. (Saya memiliki set pengaturan default untuk server kami, seperti prompt yang berwarna merah untuk root untuk memperingatkan pengguna dan sejarah besar dengan cap waktu)

Ubuntu default .bashrcdari /etc/skelmenetapkan beberapa pengaturan, yang mungkin masuk akal untuk mengatur dari suatu tempat di mana ia tidak akan mengesampingkan pengaturan yang ditetapkan oleh pemilik sistem dari /etc/profile.d(Suka /etc/bash.bashrc) (Jika pengguna mengeditnya .bashrc, boleh saja untuk menimpa pengaturan, sistem file default lebih menyebalkan)

Gert van den Berg
sumber
2

di Debian untuk sesi Terminal saya memecahkan masalah ini untuk semua pengguna jadi:

ditambahkan ke

sudo nano /etc/bash.bashrc

blok

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

dari

/etc/profile
Nikolay Baranenko
sumber
1

Ikuti jalan ini:

  • Buka Edit -> Preferensi
  • Di tab pertama "Umum", di bawah label "Perintah", aktifkan "Jalankan perintah sebagai shell masuk"
Mac
sumber
-1

VERSION = "16.04.3 LTS (Xenial Xerus)"

Oke jadi semua orang berasumsi bahwa orang di sini tidak menginginkan /etc/profile.d/somefile.sh untuk semua pengguna, tetapi dalam kasus saya itulah yang saya inginkan.

Jadi sebenarnya ketika ternyata dengan Ubuntu jika Anda menggunakan ini dan Anda ingin itu berlaku di shell grafis Anda, yang harus Anda lakukan adalah mengatur file dan kemudian logout dan kembali lagi. Semua konsol Anda atau apa pun yang Anda luncurkan, apakah itu tipe xterm atau tipe konsol (Atau jatuh ke shell) sekarang akan memiliki file yang bersumber.

Tidak perlu menggunakan .bashrc dll untuk semua pengguna. Maaf ini tidak jelas dalam jawaban di atas. Semua yang mereka katakan adalah benar tetapi pada kenyataannya sebagian besar tidak benar karena semua yang diluncurkan windows manager akan mewarisi pengaturan ini jadi login ulang dan selesaikan masalah Anda dan jangan repot-repot dengan .bashrc dll jika niat Anda adalah untuk menerapkannya ke semua pengguna .

Isaac Kane Egglestone
sumber
2
Masalah saya persis bahwa ini tidak terjadi pada terminal yang dijalankan di bawah antarmuka pengguna grafis; baik di Ubuntu 16.04.3 atau 18.04.
Thomas Arildsen