シェルスクリプトから.bashrcを正常にソースできません


51

通常~/.bashrc、このコマンドを使用してファイルをソースできます

source ~/.bashrc

しかし、これをシェルスクリプトで記述して実行しても、何も起こりません。どうして?
これを行う方法はありますか?

私のスクリプト:

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

.代わりに(ドット)も試しましたsource。同じ結果。

回答:


26

シェルスクリプトは、独自のシェルインスタンスで実行されます。すべての変数設定、関数定義などは、このインスタンス(およびおそらくその子)にのみ影響しますが、呼び出しシェルには影響しないため、スクリプトの終了後には削除されます。

対照的に、sourceコマンドは新しいシェルインスタンスを開始せず、現在のシェルを使用するため、変更は残ります。

.bashrcを読み取るショートカットが必要な場合は、次のようなシェルスクリプトの代わりにシェル関数またはエイリアスを使用します。

alias brc='source ~/.bashrc'

早速お返事をいただきありがとうございます。あなたのソリューションはうまくいくかもしれませんが、「aliac brc = ....」という行を保存するためにbashrcファイルを手動で編集する必要があります。環境変数を変更するためのGUIを開発しようとしています。そのため、別のコンピューターのbashrcファイルを手動で編集することはできません。
シャンタヌ

1
source ~/.bashrc環境を変更するシェルで実行する必要があります。別のプロセスから変更することはできません。多分(グローバルに)このエイリアスを追加することは、GUIのインストールプロセスの一部かもしれません。
フロリアンディーシュ

1
だから私はスクリプトの前にエイリアスコマンドを入れてから、.bashrcをソースしたいときにbrcを呼び出すか、そのエイリアスコマンドをどこかにファイルに入れる必要がありますか?
user137717

私がやったことは、Florian Dieschの答えの延長です。複数行のエイリアスを使用することができます:alias brc = 'chmod a + x〜/ .bashrc; source〜/ .bashrc '私はまだかなり新しいので、これが「悪い練習」と見なされるかどうかはわかりません。それは動作しますが。
A_user_appears

13

あなたの.bashrc通常開始:

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

スクリプトにはPS1が設定されていないため(インタラクティブではないため)、早期に終了するため、パスはリセットされません。デモンストレーションするには、スクリプトを変更します。

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

これにより、スクリプトが新しいで動作するようになります.bashrc。注:スクリプトが終了すると、envはスクリプトを開始する前の状態に設定されます。変更は、次に端末を起動したときに反映されます。


少なくとも16.04以降、おそらくそれ以前では、デフォルトのUbuntu .bashrcはシェルが対話型であることを確認するためにより信頼性の高い方法を使用しています。/etc/bash.bashrcPS1テストはまだあります。
ザンナ

12

試してください:

exec bash

これにより、〜/ .bashrc、〜/ .bash_aliasesなどが再ロードされます。


9
これにより、現在のbashプロセスが新しいものに置き換えられます。使用sourceするよりも短くも簡単でもありませんが、変数を破棄し、ユーザーが手動で設定したようにします。
フロリアンディーシュ

ちょっと待って、bashrcソーシング後の他のコマンドを使用したシェルスクリプトのコンテキストで、その後に新しいbash状態を必要とするコマンドを配置しますexec bashか?
タツ

11

私はラビの答えを補完したい:

デフォルトの~/.bashrcファイルは、Ubuntu 18.04などのショートサーキットで始まるため、この動作はUbuntu(およびおそらく最も派生したディストリビューション)に固有です。

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

すべてのスクリプトは非対話型シェル実行されるため、スクリプトの場合は非対話型シェルで実行されている場合、ファイルの評価を停止しsourceます。その後、このプロパティを継承するすべてのファイル。

eval ハック

私が使用して、特にUbuntuのを回避するために醜いハックを見つけたevalのではなくsource

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

最初の数行をスキップし、残りの行を評価するだけな~/.bashrcので、残りの行が評価され、現在の実行が変更されます。

これはマジックナンバーであり、Ubuntuのバージョン間で機能しない可能性があることに注意してください。しかし、多かれ少なかれ既知のシステム用のスクリプトを作成している場合には、良い解決策かもしれません。

より洗練されたソリューションには、正規表現を使用して、評価を停止する特定のビットをターゲットにすることが含まれる場合があります。

シバン代替

いくつかのシナリオでうまく機能する可能性のある別の代替方法は、shebangにフラグを追加することにより、スクリプトを強制的に対話型シェルで実行することです。

#!/bin/bash -i

いくつかのことに注意してください:


2

このチュートリアルのおかげで、以下を使用することがわかったまで、他のメソッドはどれも私にとってはうまくいきませんでした[ source /path/to/filevs . ./path/to/file、エイリアスなど...] 。

#!/usr/bin/env bash シバン

より単純な#!/usr/bin/envものの代わりに、引数をインタープリターに渡すことができます。これがここで重要だと思います-詳細については、このドキュメントを参照してください。

いずれにしても、何らかの形式のソースコマンドが機能しない場合は、シェバンを確認してみてください。それが問題の可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.