Bashスクリプトがエイリアスを認識しないのはなぜですか?


216

私の~/.bashrcファイルには2つの定義があります:

  1. commandA、これは長いパスのエイリアスです
  2. commandB、これはBashスクリプトのエイリアスです

これら2つのコマンドで同じファイルを処理したいので、次のBashスクリプトを作成しました。


#!/bin/bash

for file in "$@"
    do
    commandA $file
    commandB $file
done

セッションからログアウトして再度ログインした後でも、command not foundこのスクリプトを実行すると、Bashは両方のコマンドのエラーを表示します。

私は何を間違えていますか?


10
ところで、エイリアスを認識させるためにログインおよびログアウトする必要はありません。あなただけを行う必要がありますsource ~/.bashrc
シェパン

私の場合、SSHエージェントを閉じて再度接続したときにエイリアスを追加した後、リモートでSSHエージェントによって接続されました。
ダブ

エイリアスは、コマンドを短縮する方法です。(スクリプトではなくインタラクティブシェルでのみ使用されます。これは、スクリプトとインタラクティブシェルのわずかな違いの1つです。)
Kris Roofe

回答:


117

まず、ddeimekeが言ったように、デフォルトではエイリアスは非対話型シェルでは展開されません。

第二に、環境変数.bashrcを設定しない限り、非対話型シェルによって読み取られませんBASH_ENV

しかし、最も重要なこと:それをしないでください!お願いします?ある日、必要なエイリアスが設定されていない場所にスクリプトを移動すると、再び壊れます。

代わりに、環境変数をスクリプトのショートカットとして設定して使用します。

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
do
    $CMDA "$file"
    $CMDB "$file"
done

5
このソリューションは、通常のaliasユースケースでは機能しません。例えばalias mv="mv -v --backup=numbered"
Evi1M4chine

@ Evi1M4chine:はい、そうです。少なくとも、ジルの不要な編集を元に戻した後。しかし、とにかく、パラメーターに別の変数を使用する方が良い場合があります。

1
ああ、/の周りに引用符がないことに注意してください...大文字の変数がbashでbash自体のために予約されていることを除けば、実際に動作します。$CMDA$CMDB
Evi1M4chine

@ Evi1M4chine:あー、何?1.最新の編集で引用符を自分で削除しました。2.「bash自体の予約」はどこから入手しますか?これは私が聞いた最初のものです。3. それがあなたを不安にさせるなら、そもそもbashを使うことについてどう思いますか?とにかく、私があなたに言ったように、オプションに別の変数を使用します。

1
@alvas:仮定はgizmo、パス上にないか、同じ名前でより高い優先度のコマンドがあることです。それ以外の場合は、そもそも単純CMDAにプレーンgizmoに設定できます。

161

bashのマンページを見ると、次のことがわかります。

シェルが対話型でない場合、shoptを使用してexpand_aliasesシェルオプションが設定されない限り、エイリアスは展開されません(以下のSHELL BUILTINコマンドの下のshoptの説明を参照)。

だから

shopt -s expand_aliases

スクリプトで。

スクリプトでこれを設定した後、必ずエイリアスファイルを入手してください。

shopt -s expand_aliases
source ~/.bash_aliases

7
スクリプトに配置しましたが、まだ機能していません。同じエラー。
ザイド

5
追加することshopt -s expand_aliases source ~/.bash_aliasesは私にとって完璧に機能します。.bashrcには、次のような対話型のシェル検出形式がよくあり# If not running interactively, don't do anything [ -z "$PS1" ] && returnます。
フランクシューベルト

1
優れた!スクリプトを保存しました!! :) ...インターネット上で検索/ /検索を読んで、私はちょうどずっと前にあきらめたの端末に情報およびマンページを参照して行くことに一生懸命である
アクエリアスパワー

2
奇妙なshopt -s expand_aliasesことに、エイリアス定義の前ではなく、エイリアスの使用前に行く必要があります。@FrankSchubertへの追加:シェル$-のオプションが含まれるシェルを使用して、特にiシェルが対話型である場合、対話型シェル検出を実行することもできます。
有効

2
これは正しい答えではありません...スクリプト内でエイリアスを調達することは答えではありません。あなたは、~/.bash_aliases私が見つけた最も近いものがにあなたのhashbangを変更している...以前、対話型シェルにロードされた他のものに依存する場合があります#!/bin/bash -liまだ完璧ではありません。理想的には、エイリアスではなく関数を使用する必要があります。
ステファノスカランツィス16

44

エイリアスはエクスポートできないため、定義されていないシェルスクリプトでは使用できません。言い換えれば、それらを~/.bashrc使用できない場合に定義する場合your_script.sh~/.bashrcスクリプトでソースを指定しない限り、これはお勧めしませんが、これを適切に行う方法があります)。

ただし、関数はエクスポートでき、定義されている環境から実行されるシェルスクリプトで使用できます。これは、これをbashrcに配置することで実行できます。

foo()
{
    echo "Hello World!"
}
export -f foo

Bashのマニュアルにあるように、「ほぼすべての目的で、シェル関数はエイリアスよりも優先されます。」


1
これは技術的に質問に答えていませんが、あなたは簡単に取り替えることができると言うようalias commandA=...commandA() { ... }、その後export commandA、あなたはエイリアスと同じ動作を得ます。だから、これはかなりのbashスクリプトで素晴らしい作品私の知る限りでは、エイリアスと同じ選択肢である
Phylliida

ここでの問題は、引用符で囲まれた多くのオプションを渡すエイリアスが必要な場合です。たとえば、例としては、関数で実行するのが難しい操作をalias b=bash簡単にしb -c "echo test | grep test"ます。
Fmstrat

@Fmstrat:b () { bash "$@"; }その後b -c "echo test | grep test"
デニスウィリアムソン

11
[cmd line] > bash -i [your script's file path]

これiは、インタラクティブであり、bashプロファイルを提供します。


-5

bashスクリプトがエクスポートを認識しないこともあります。ただし、それを

#!/bin/sh

私のために働く。


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