回答:
シェルスクリプトは、独自のシェルインスタンスで実行されます。すべての変数設定、関数定義などは、このインスタンス(およびおそらくその子)にのみ影響しますが、呼び出しシェルには影響しないため、スクリプトの終了後には削除されます。
対照的に、sourceコマンドは新しいシェルインスタンスを開始せず、現在のシェルを使用するため、変更は残ります。
.bashrcを読み取るショートカットが必要な場合は、次のようなシェルスクリプトの代わりにシェル関数またはエイリアスを使用します。
alias brc='source ~/.bashrc'
source ~/.bashrc環境を変更するシェルで実行する必要があります。別のプロセスから変更することはできません。多分(グローバルに)このエイリアスを追加することは、GUIのインストールプロセスの一部かもしれません。
あなたの.bashrc通常開始:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
スクリプトにはPS1が設定されていないため(インタラクティブではないため)、早期に終了するため、パスはリセットされません。デモンストレーションするには、スクリプトを変更します。
#!/bin/bash
chmod a+x ~/.bashrc
PS1='$ '
source ~/.bashrc
これにより、スクリプトが新しいで動作するようになります.bashrc。注:スクリプトが終了すると、envはスクリプトを開始する前の状態に設定されます。変更は、次に端末を起動したときに反映されます。
.bashrcはシェルが対話型であることを確認するためにより信頼性の高い方法を使用しています。/etc/bash.bashrcPS1テストはまだあります。
試してください:
exec bash
これにより、〜/ .bashrc、〜/ .bash_aliasesなどが再ロードされます。
sourceするよりも短くも簡単でもありませんが、変数を破棄し、ユーザーが手動で設定したようにします。
exec bashか?
私はラビの答えを補完したい:
デフォルトの~/.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
いくつかのことに注意してください:
#!/usr/bin/env bashフォームがありますが、このような引数でシェルを起動することはできませんが。-i独自の結果セットがありますが、プログラムはユーザーとの対話を促します。これは通常、スクリプトを対象としてdebいません。たとえば、パッケージをインストールすると、dpkg configureプロンプトでスクリプトが停止する場合があります。set -iしset +iたりオンまたはオフにしようとしましたが、これは機能しません。このチュートリアルのおかげで、以下を使用することがわかったまで、他のメソッドはどれも私にとってはうまくいきませんでした[ source /path/to/filevs . ./path/to/file、エイリアスなど...] 。
#!/usr/bin/env bash シバン
より単純な#!/usr/bin/envものの代わりに、引数をインタープリターに渡すことができます。これがここで重要だと思います-詳細については、このドキュメントを参照してください。
いずれにしても、何らかの形式のソースコマンドが機能しない場合は、シェバンを確認してみてください。それが問題の可能性があります。