web-dev-qa-db-ja.com

Sudoがエイリアスを無視するのはなぜですか?

Ubuntu 10.04を実行していますが、デーモン管理にupstartを使用しています。私のエンタープライズアプリケーションはデーモンとして実行されており、さまざまな特権のためにrootとして実行する必要があります。例えば。:

Sudo start my-application-long-ID
Sudo stop my-application-long-ID
etc

これらのコマンドを以下のように短縮するためにaliasを紹介したいと思います。

alias startapp='Sudo start my-application-long-ID'

startappとして実行すると機能しますが、エイリアスにSudoを含めない方がよいでしょう。

alias startapp='start my-application-long-ID'

Sudo startappを使用して実行するとSudo: startapp: command not foundが返されません。

しかし、エイリアスを追加したとき:

alias Sudo='Sudo '

Sudo startappが機能するようになりましたが、Sudoがエイリアスを無視する理由を知りたいです。

23
amphibient

here から以下の情報が表示されます。

Sudoを使用する場合は、エイリアス拡張を使用します(そうでない場合、Sudoはエイリアスを無視します)

alias Sudo='Sudo '

動かない理由を説明します こちら

Bashはコマンドの最初の単語のみをチェックし、その後の単語はチェックされません。つまり、Sudo llのようなコマンドでは、最初のWord(Sudo)のみがbashによってエイリアスがチェックされ、llは無視されます。エイリアス値の最後にスペースを追加することで、エイリアス(つまりSudo)の後の次のワードをチェックするようにbashに指示できます。

36
Ramesh

エイリアスと関数はシェルで定義されます。 Sudoは外部プログラムです。したがって、Sudoはエイリアス、関数、またはシェルの組み込みコマンドを認識せず、外部コマンドのみを認識します。

エイリアスは代替のコマンド名であることを意図しているため、シェルはコマンドの引数である場合ではなく、コマンドの位置でのみそれらを展開します。 Zshはグローバルエイリアスをサポートします。これはコマンドラインの任意の場所で展開され、エイリアスが意味をなさないコンテキストでも誤って展開するリスクがあるため、控えめに使用することをお勧めします。

Sudoにシェルを呼び出すように指示できます:Sudo sh -c '…Shell command here…'。ただし、通常のエイリアスは~/.bashrc~/.zshrcなどのファイルに保存され、インタラクティブシェルでのみ読み取られるため、通常のエイリアスはそのShellコマンド内では使用できません。

alias Sudo='Sudo 'Rameshによって提案 として、シェルがSudoの後にエイリアスを展開します。

Zshユーザー向けのソリューション

Bashとzshの両方で、スペースでエイリアスを終了すると、シェルは次のWordをエイリアス展開します。これにより、次のようなエイリアスを展開できますmyalias

alias 'Sudo=sudo '
Sudo myalias

残念ながら、エイリアスに複数のWordがある場合(Sudo -u someoneのように)、これはばらばらになります。ただし、zshの「グローバルエイリアス」機能を悪用して、コマンドの任意の場所でエイリアスを手動で展開できます。

alias -g '$= '

これにより、スペースで終わる$(任意のWordを使用できます)というグローバルエイリアスが作成されます。これにより、zshは次のWordを通常のコマンドエイリアスとして展開します。エイリアスは空白に展開されるため、引数として扱われません。これにより、以下が機能します。

% alias myalias=echo
% Sudo -u someone myalias foo
Sudo: myalias: command not found
% Sudo -u someone $ myalias foo
foo

複雑なコマンドのネストがある場合は、1つのコマンドラインで$を複数回使用することもできます。これは、zshrcに永続的に配置するのに十分便利であることがわかりましたが、エイリアスは、いつ使用する必要があるかを定義するのに十分なほど単純です。

1
Kevin Cox

Sudoをエイリアスで再定義せずに、代わりの回答 here を指定しました。

あなたの場合は次のようになります:

type -a startapp | grep -o -P "(?<=\`).*(?=')" | xargs Sudo 

すべて1行で、追加のシェルやエイリアスの再定義はありません。 ;-)

0
loved.by.Jesus