Pertanyaan Tidak dapat berhasil sumber .bashrc dari skrip shell


Biasanya kami dapat sumber ~/.bashrc file menggunakan perintah ini

source ~/.bashrc

tetapi jika saya menulis ini dalam skrip shell dan menjalankannya, tidak ada yang terjadi. Mengapa?
Apakah ada cara untuk melakukan ini?

kode cangkang saya:

#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc

Juga dicoba .[dot] dari pada source. Hasil yang sama


36
2017-10-05 11:50


asal




Jawaban:


Skrip shell dijalankan dalam contoh cangkangnya sendiri. Semua pengaturan variabel, definisi fungsi dan hanya mempengaruhi contoh ini (dan mungkin anak-anaknya) tetapi bukan shell panggilan sehingga mereka hilang setelah skrip selesai.

Sebaliknya, source perintah tidak memulai contoh shell baru tetapi menggunakan shell saat ini sehingga perubahan tetap.

Jika Anda ingin cara pintas untuk membaca .bashrc Anda menggunakan fungsi shell atau alias, bukan skrip shell, seperti

alias brc='source ~/.bashrc'

22
2017-10-05 12:16



Terima kasih atas jawaban cepat Anda. Solusi Anda mungkin bekerja tetapi saya harus mengedit file bashrc secara manual untuk menyimpan baris 'aliac brc = ....'. Saya mencoba mengembangkan gui untuk mengubah variabel lingkungan. Jadi saya tidak bisa mengedit file bashrc komputer lain secara manual. - shantanu
Anda harus berlari source ~/.bashrc di shell yang Anda ingin mengubah lingkungan. Anda tidak dapat mengubahnya dari proses lain. Mungkin (global) menambahkan alias ini bisa menjadi bagian dari proses instalasi GUI Anda. - Florian Diesch
jadi apakah saya meletakkan perintah alias Anda sebelumnya di skrip dan kemudian memanggil brc ketika saya ingin sumber saya .bashrc atau saya perlu menempatkan perintah alias itu dalam file di suatu tempat? - user137717
Apa yang akhirnya saya lakukan adalah perpanjangan jawaban Florian Diesch. Anda bisa menggunakan alias multi-baris: alias brc = 'chmod a + x ~ / .bashrc; source ~ / .bashrc 'Saya masih cukup baru, jadi saya tidak yakin apakah ini dianggap' latihan yang buruk '. Itu berhasil meskipun. - A_user_appears


Mencoba:

exec bash

Ini harus memuat ulang ~ / .bashrc, ~ / .bash_aliases, dll.


12
2017-10-05 12:37



terima kasih untuk balasan Anda. Ia bekerja tetapi menggantung prosesnya. - shantanu
Ini menggantikan proses bash saat ini dengan yang baru. Tidak jauh lebih pendek atau lebih mudah daripada menggunakan source tetapi menghancurkan variabel apa pun dan sedemikian rupa sehingga pengguna telah mengatur secara manual - yang mungkin atau mungkin tidak seperti yang Anda inginkan. - Florian Diesch


Anda .bashrc biasanya dimulai:

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

Karena skrip Anda tidak memiliki set PS1 (karena tidak interaktif), itu tidak mereset path karena ia keluar lebih awal. Untuk menunjukkan, ubah skrip Anda:

    #!/bin/bash
    chmod a+x ~/.bashrc
    PS1='$ '
    source ~/.bashrc

ini sekarang akan memungkinkan skrip Anda bekerja dengan yang baru .bashrc. Catatan: setelah skrip Anda keluar, env akan diatur ke kondisi sebelum memulai skrip. Perubahan akan tercermin saat berikutnya terminal dimulai.


9
2017-11-08 11:11





Tidak ada metode lain yang berhasil untuk saya [source /path/to/file vs . ./path/to/file, alias, dll ...], hingga, terima kasih kepada tutorial ini Saya menemukan bahwa menggunakan:

#!/usr/bin/env bash peristiwa

bukannya yang lebih sederhana #!/usr/bin/env salah satu memungkinkan argumen diteruskan ke interpreter, yang menurut saya adalah kuncinya di sini - lihat dokumen ini untuk info lebih lanjut.

Dalam hal apa pun, jika perintah sumber dalam bentuk apa pun tidak bekerja untuk Anda, coba periksa shebang Anda, mungkin itu masalahnya :)


2
2017-08-21 01:40





Saya ingin melengkapi jawaban ravi:

Perilaku ini khusus untuk Ubuntu (dan mungkin distro yang paling turunan), sejak default Anda ~/.bashrc file dimulai dengan sirkuit pendek, Ubuntu 18.04, misalnya:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Itu akan menghentikan evaluasi file jika itu berjalan dalam shell non-interaktif, yang merupakan kasus skrip Anda sejak itu semua skrip dijalankan dalam shell non-interaktif, dan selanjutnya setiap file Anda source akan mewarisi properti ini.

eval meretas

Saya menemukan sebuah hack yang buruk untuk mengatasi Ubuntu secara spesifik, menggunakan eval dari pada source:

eval "$(cat ~/.bashrc | tail -n +10)"

Ini hanya melompati beberapa baris pertama dan mengevaluasi sisanya ~/.bashrc sehingga sisanya dievaluasi dan dimodifikasi saat ini.

Sadarilah itu adalah angka ajaib dan mungkin tidak berfungsi di versi Ubuntu; tetapi mungkin merupakan solusi yang baik jika Anda menyusun skrip untuk sistem yang lebih dikenal atau kurang.

Solusi yang lebih bagus mungkin melibatkan penggunaan regex untuk menargetkan bit spesifik yang menghentikan evaluasi.

Shebang alternatif

Alternatif lain yang mungkin bekerja lebih baik dalam beberapa skenario adalah memaksa skrip untuk berjalan dalam shell interaktif dengan menambahkan bendera di peristiwa:

#!/bin/bash -i

Sadarilah beberapa hal:

  • ini latihan yang lebih baik untuk menggunakan #!/usr/bin/env bash bentuk tetapi dengan cara ini Anda tidak dapat memulai shell dengan argumen.
  • Menggunakan -i memiliki serangkaian konsekuensi sendiri, di antaranya, program akan meminta interaksi pengguna dan ini biasanya tidak dimaksudkan untuk skrip, misalnya, menginstal deb paket mungkin menghentikan skrip di dpkg configure meminta.
  • Saya awalnya mencoba menggunakan set -i dan set +i untuk menghidupkan dan mematikan fitur di mana saya membutuhkannya, tetapi ini tidak berhasil.

2
2018-05-28 21:08