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


22

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

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がエイリアスを無視するのか興味があります。


走りましたsource ~/.bashrcか?これにより、.bashrcファイルが更新され、新しいエイリアスが使用可能になりますか?
マヌー14

@manuはい、そうしました
両生類14

回答:


35

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

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

alias sudo='sudo '

動作しない理由をここで説明します

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


6

エイリアスと関数はシェルで定義されます。sudoは外部プログラムです。そのため、sudoはエイリアス、関数、またはシェルビルトインを認識せず、外部コマンドのみを認識します。

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

sudoにシェルを起動するように指示できますsudo sh -c '…shell command here…'。あなたのいつもの別名は、彼らは通常のようなファイルに保存されているので、シェルコマンド、しかし、ことを利用できる内部のではないだろう~/.bashrcか、~/.zshrcこれだけのインタラクティブシェルによって読み取られます。

alias sudo='sudo 'Rameshによって提案されるように、シェルは後に別名を広げますsudo


1
alias sudo='sudo 'ZSHのための作業にも?
CMCDragonkai


1

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

bashとzshの両方で、エイリアスをスペースで終了すると、シェルは次の単語をエイリアス拡張します。これにより、以下のようなものがエイリアス展開することができますmyalias

alias 'sudo=sudo '
sudo myalias

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

alias -g '$= '

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

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

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


0

ここsudoでは、エイリアスで再定義せずに別の回答を示しました

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

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

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


ちょっと待ってください-わかりました-あなたはxargs引用符を取り除き、grepを使って先頭を取り除き=ます。ちょっと賢いですが、おそらく不要です。eval "sudo $(alias aliasname | cut -d= -f2-)"おそらくより良いです- xargs常に引用符を正しく処理するとは限りません=
mikeserv

@mikeserv申し訳ありませんが、それを入手できなかった;-) xargs引用符を削除しないでください。引用符の間から解決されたコマンドを取得するのはgrepです。のtype -a alias_nameようなものを返しますalias_name is aliased to command_within_quotes。ちなみに私はあなたのコマンドを試してみましたが、私のUbuntu :-(に仕事をしませんでした、それはのリターンです。type -aLinuxのバージョン間で異なる(私はそれを疑う)?。
loved.by.Jesus

私が知っているtype中で-ませんbash。ただし、引用符が2倍になることを理解していますか?一重引用符を含むエイリアスで試してみましたか?とにかく、あなたは私のものが機能していないことについて正しいです-あなたはどちらeval "sudo sh -c "$(...かが必要eval "'sudo $(alias alias_name| cut -d\' -f2-)"です。事はあるaliasESは基本的に予定されているevalのを- aliasそれは安全に再入力シェルにすることができるようにユーティリティが出力にその内容をspec'dされます。xargs空白を平坦化するために実装されていると思いますか?気をつけてね
mikeserv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.