BASHスクリプトはオプションで動作します。

BASHスクリプトはオプションで動作します。

/etc/bash.bashrc長く使ってきたBASH機能がたくさんあります。彼らは~/.bashrcOSXの内外で~/.bash_profile次のように動作します。

mcdir(){
    mkdir "$1";
    eval cd "$1";
}

これは短い例に過ぎず、毎日使用しています。それは与えられたディレクトリを作成し、それを変更するだけです。mkdir "$1" && cd "$1"私は怠惰なだけです。

ポイントは効果があるということです。長年使ってきたので効果があることを知っています。

これで最近これをmyから削除して(and)にbashrc入れたので、実際には何も変更されませんでした。ここでは次のようになります。/usr/local/binmcdirchmod +x /usr/local/bin/mcdir

#!/bin/bash

mkdir "$1";
eval cd "$1";

すべての意図と目的のために、これは上記の機能とまったく同じでなければなりません。問題は半分しか機能しないということです。新しいディレクトリが作成されますが、いいえそれに変えなさい。

私がここで何を間違っているのか、そして/または解決策を知っている人はいますか?


私が持っているもう一つの例は、次の関数cddです。bashrc

cdd(){
    cd "$1";
    echo -e "\033[101m" $(pwd) "\033[49m";
    ls -l;
}

これは非常にうまく動作します!しかし、それを独自のスクリプトに入れて、次/usr/local/binのように実行可能にする場合:

cd "$1";
echo -e "\033[101m" $(pwd) "\033[49m";
ls -l;

実際にはディレクトリに変更されません。これにより、pwdこれが提供されますが、ls -lディレクトリはまったく変更されません。

答え1

スクリプトはサブシェルで実行されます。関数と同じ方法でアクティブなシェルセッションの環境に影響を与えることはできません。例えば高度なBashスクリプトガイド、第21章:サブシェル:

サブシェルは、命令プロセッサの別々のインスタンスです。シェルこれにより、コンソールまたはコンソールにプロンプ​​トが表示されます。xterm窓。コマンドラインプロンプトでコマンドが解釈されるように、スクリプトも同様に解釈されます。バッチ処理コマンドのリスト。実行される各シェルスクリプトは実際に子プロセス(サブプロセス)のシェル。

またはBashリファレンスマニュアル、セクション3.8:シェルスクリプト:

chmod コマンドを使用して実行ビットをオンにすると、シェルスクリプトを実行可能にできます。 Bashがコマンドを検索している間にこれらのファイルを見つけると、$PATHそれを実行するためのサブシェルが作成されます。つまり、実行

filename arguments

実行と同じ

bash filename arguments

if はfilename実行可能なシェルスクリプトです。サブシェルはそれ自体が再初期化されるため、親シェルがコマンドの場所を覚えていることを除いて、スクリプトを解釈するために新しいシェルが呼び出されたのと同じ効果があります(hash説明を参照)。Bourne Shell 組み込み関数)は子供が保管します。

関数の代わりにスクリプトを使用したい場合はsource、実行する代わりに使用すれば良いのですが、正直に今やっていることには関数(またはエイリアス)を使い続ける方が良いと思います。

つまり、コードを再構成するには、~/.bashrcコードを別のファイルに分割してからファイルsourceをから移動できます~/.bashrc。たとえば、そのファイルをローカルサブディレクトリ(たとえば)に配置できます~/.bashrc.d

関連情報