チルダ拡張とBashの変数

4
2021.12.30

次のスニペットを検討してください。

 $ export xx=foo
$ sudo bash -c 'echo $xx ~'
/root

大丈夫です。 xxが見えません。

しかし、私がそれを公開した場合:

 $ sudo -E bash -c 'echo $xx ~'
foo /home/xropi

多くの人がはエイリアスではないと言いますが、-Eがオリジナルを公開して評価を延期できないため、どういうわけかそれは環境の一部です。

sudo-edコマンドで変数を渡して〜を/ rootとして評価することは可能ですか?

sudoで実行するときにこれを取得したい:

 foo /root
回答
11
2021.12.30

チルダがどのように機能するかについてのあなたの理解は不完全です。 man bashを参照してくださいTilde Expansionを検索します。

それは(余分な改行と私が追加したいくつかの太字)で始まります:

単語が引用符で囲まれていないチルダ文字( ~ )で始まる場合、最初の引用符で囲まれていないスラッシュの前にあるすべての文字(または引用符で囲まれていないスラッシュがない場合はすべての文字)がチルダプレフィックスと見なされます。

チルダプレフィックス内の文字が引用符で囲まれていない場合、チルダに続くチルダプレフィックス内の文字は可能なログイン名として扱われます。

このログイン名がnull文字列の場合、チルダはシェルパラメータHOMEの値に置き換えられます。 HOMEが設定されていない場合は、代わりにシェルを実行しているユーザーのホームディレクトリに置き換えられます。

それ以外の場合、チルダプレフィックスは指定されたログイン名に関連付けられたホームディレクトリに置き換えられます。

つまり、 $ HOMEが空でない場合、~は$ HOMEに展開されます。

-Eなしで実行するとsudoは($HOMEを含む)は、ユーザーの環境変数を保持されません。 -Eを使用すると、そうなります。

ところで、これも注目に値します。ほとんどのシェルは~を拡張してユーザーのホームディレクトリを意味することができますが、すべてのプログラムが拡張できるわけではありません。実際、ほとんどのプログラムはそうではありません-それを行うのは実際には彼らの仕事ではありません、彼らは引数を見る前にチルダと変数とグロブと他の拡張を実行するためにシェルに依存しています。


質問:sudo-edコマンドで変数を渡して〜を/ rootとして評価することは可能ですか?

いくつかの方法があり、それぞれに長所と短所があります。それらのいくつかを次に示します。

  1. unset HOMEを実行する前のsudo -E

  2. HOME=/rootを実行する前にsudo -Eを設定します。例: HOME=/root sudo -E bash -c 'echo $xx ~'

  3. sudoと共有する変数をファイルに書き込みます。例えば、あなたはdeclare -p var1 var2 var3 > /tmp/myvars.shを実行し、(-Eなし)sudoを持っている、それはあなたがsudoで実行することは何でも実行する前に、source /tmp/myvars.shを行うシェルスクリプトを実行することができます。

  4. /etc/sudoersまたは/etc/sudoers.d/*env_keepの設定を使用する-これはとか、-Eオプションを指定しないで、sudoの実行時に常に保持される変数を定義することができます。

  5. (このオプションは、環境変数名のカンマ区切りのリストを取る)xx変数を渡すためにsudoを伝えるためのホームディレクトリと--preserve-env=xx使用sudoターゲットユーザーへのセットHOME秒-Hオプション」(@MichaelHomerから)。詳細については、 man sudoを参照してください。すべてのユーザーが環境を保護する権限を持っているわけではないことに注意してください。 man sudoersを参照してください。

sudoはENVは、デフォルトではvarsは保持されませんなぜ正当な理由があることに注意してください。深刻なセキュリティ上の影響を与える多くのenv変数があり、その誤用により、ユーザーまたはグループがアクセスしてはならないものへのルート(または他のuid)アクセスを取得する可能性があります。