"bash: !/bin/su": イベントが見つかりません"

"bash: !/bin/su": イベントが見つかりません"

私のスクリプトには機能する行がありますが、コマンドラインからは実行できません。

echo "User ALL = NOPASSWD: ALL, !/bin/su" | sudo tee -a /etc/sudoers



[user@localhost ~]$ echo "test ALL = NOPASSWD: ALL, !/bin/su" | sudo tee -a /etc/sudoers
bash: !/bin/su": event not found
[user@localhost ~]$

編集:コマンド権限なしでsudoユーザーを追加しようとしていますが、susudoユーザーが利用可能ですsudo -i。私はちょうどそのスクリプトのすべてのコマンドをチェックして、コマンドラインでどのように機能するかを確認しました。

使用する必要がある回避策をコマンドラインで見つけました"'!'"/bin/su。これがコマンドラインで機能しない理由を説明できる人はいますか?

答え1

[あなたは正しい方法で仕事をしていないようです。あなたの質問に関連するコメントをよく読んでください。sudo]

には、bashコマンドラインで有効にできる「記録の置き換え」というメカニズムがあります。これにより、前のコマンドの全部または一部を編集中のコマンド(したがって「history」という名前)に挿入できます。

履歴の交換をトリガーする文字はです!。たとえば、!WORDで始まる最後のコマンドで置き換えますWORD。そのようなコマンドがないと、bash次のエラーメッセージが表示されますbash: !WORD: event not found

!履歴置換メカニズムを有効にせずにaを入力する必要がある場合は、エスケープするか、\!単一引用符で囲む必要があります'!'

たとえば、echo 'User ALL = NOPASSWD: ALL, !/bin/su' | ...

履歴拡張が面倒な場合は、を使用して無効にし、set +H引用符なしでコマンドを入力し、後でを使用して!再度有効にすることもできますset -H

答え2

  1. suルートには特別な権限は与えられません。したがって、rootアクセス権を持つ人がそれを使用するのを防ぐことは意味がありません。
  2. 元のファイルsudoを展開visudoします。sudo/etc/sudoers.d/
  3. エスケープする必要があります!"bla bla bla \! bla bla"それ以外の場合、'bla bla bla ! bla bla'一重引用符は停止します。みんな文字列評価。

答え3

sudo私は、これが特権ユーザーがsuコマンドを実行するのを防ぐのに役立たないと思います。sudoこれは、権限を持つすべてのユーザーが自分のプライマリディレクトリからコピーしてそれを実行できるためです。いつものように、ユーザーに完全な権限を与えてからコマンドを実行するのを防ぐsuことはできません。sudo特定のことをすることは、神が常に制限を避ける方法を見つけることができるので、あなたはその反対の仕事をして彼にいくつかの特権を与えなければなりません。

関連情報