私はOpenboxウィンドウマネージャでArchとbashを使用しています。
すべてが最新の状態です。
Openboxは次のように構成されています。rc.xml
内部的には、通常、必要な一連の便利なコマンドをショートカットに接続するためrc.xml
に呼び出します。bash -c 'command1; command2; etc'
rc.xml
次のように定義されたショートカットがあります
<keybind key="1"><action name="Execute"><command>bash -c '
command1;
command2;
etc;
yad --timeout=1 --text="$pos_x x $pos_y";
'</command></action></keybind>
$pos_x
グローバルに定義されて表示されない変数を除いて、すべてが期待どおりに機能し、完全に機能します$pos_y
。
これは.bashrc
次のように定義されます。
export pos_x=1000
export pos_y=500
新しいbashシェルターミナルウィンドウを開いて入力すると、予想される1000 x 500が
echo "$pos_x x $pos_y"
表示されます。
ただし、この新しい端末ウィンドウに入力すると、
bash -c 'echo "$pos_x x $pos_y"'
子プロセスはグローバル変数を継承しないため、何も表示されません。
入力すると
bash -c 'source ~/.bashrc; echo "$pos_x x $pos_y"'
何も表示されないため、子プロセスから.bashrcをインポートすることは役に立ちません。
定義されたグローバル変数を.bashrc
子プロセスに渡すには?
私は周りを見回したが、答えが見つかりませんでした。
答え1
Archのデフォルト設定には、~/.bashrc
ファイルの上部に次の行が含まれています。
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
これにより、非対話型シェルはその行からファイルの読み取りを停止します。bash -c
非対話型シェルが起動されるため、ファイル~/.bashrc
全体を読み取ることができないため、変数は定義されません。
したがって、次のことを試すことができます。
~/.profile
代わりに変数を入れてください~/.bashrc
。とにかく、これはグローバル変数の自然な場所です。ログイン管理者がこの内容を読む限り、/.profile
機能します。別のファイルを使用してください。そこに変数定義を入れる必要はありません
~/.bashrc
。変数定義を入れて~/foo
からコマンドを実行するだけですbash -c '. ~/foo; echo "$pos_x x $pos_y"
。読み取りを停止する最初の部分に表示された行の上に変数定義を配置します
~/.bashrc
。
答え2
~からGNU Bash マニュアル、6.2 Bash 起動ファイル:
Bashが対話型ログインシェルとして呼び出される場合
/etc/profile
、またはファイルが存在する場合は、最初にファイルからコマンドを読み込んで実行する --login オプションを持つ非対話型シェルとして使用されます。ファイルを読み込んだ後~/.bash_profile
、、~/.bash_login
順に探して~/.profile
命令を読み出して実行する。 最初存在し、読むことができます。 ...Bashが非対話式で始まるときたとえば、シェルスクリプトを実行するには、環境でBASH_ENV変数を見つけてその値が表示されたら拡張し、拡張値を読み取って実行するファイル名として使用します。
したがって、環境を正しく設定するには、Bashがインタラクティブになっているのか非対話式になっても、単に持つだけでは不十分であり、変数を設定してそれを指して~/.bash_env
対話BASH_ENV
モードで明示的にインポートする必要があります。
Bash関連のエントリをBash関連のファイルに入れ、~/.profile
他のシェルで動作し続ける一般設定を維持します(いつかログインシェルを変更することにした場合)。
まず、~/.bash_profile
次の内容でファイルを作成します。
[ -f "$HOME/.profile" ] && source "$HOME/.profile"
if [ -z "$POSIXLY_CORRECT" ]; then
[ -z "$BASH_ENV" ] && export BASH_ENV="$HOME/.bash_env"
source "$BASH_ENV"
fi
"$HOME/.bash_env"
次に、すべてのBash関連の変数と関数を含むファイルを作成します。
順序が重要です。ソース行を~/.profile
一番上に置くと、~/.bash_profile
Bashの実行時にそこに定義されている変数をオーバーライドできます。
BASH_ENV
変数が参照するファイルが、リモートシェルデーモン(通常rshd
)またはセキュアシェルデーモンによって呼び出されたときに取得されたものであることを確認していませんsshd
。 Bashのマニュアルを再び引用するには、
Bashがこのように非対話型で実行されていると判断した場合、コマンドを読み込んで実行します
~/.bashrc
(ファイルが存在して読み取れる場合)。
以下を含むものを作成することをお勧め~/.bashrc
します。
if [ -z "$POSIXLY_CORRECT" ]; then
[ -z "$BASH_ENV" ] && export BASH_ENV="$HOME/.bash_env"
source "$BASH_ENV"
fi
この場合、以下を簡素化できます~/.bash_profile
。
[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"
最後に、次の項目に複数の項目が含まれないように保護したいと思います~/.bash_env
。
[ -n "$BASH_ENV_VERSION" ] && return 0
BASH_ENV_VERSION=.....
...
export
~/.bash_env
注:現在のシェルから関数定義にアクセスできるようにするには、スクリプトをインポートする必要があるため、変数(またはファイル全体のすべての変数)を指定することは意味がありません。同じ理由で、私たちが作成するファイルにshebang行は必要ありません。
対話型ログインシェルと非対話型シェルの両方を扱いました。注意深い読者は、不足している部分がログインではなく対話型シェルであることに反対する可能性があります。幸いなことに、上記の手順では次の手順を実行します。
ログインシェルではなく対話型シェルを起動すると、Bash はファイルが存在する場合は ~/.bashrc からコマンドを読み込み実行します。