別のユーザーとしてスクリプトを開始する


12

/etc/init.d/にスクリプトを作成しました。このスクリプトは、他の(ルート以外の特権を持つ)ユーザーからホームディレクトリから他のスクリプトをいくつか実行する必要があります。

これらのスクリプトを次のもので起動します。 sudo -b -u <username> <script_of_a_particular_user>

そしてそれは動作します。ただし、実行を継続するすべてのユーザースクリプト(ウォッチドッグなど)には、対応する親sudoプロセスが表示されますが、まだ生きており、rootとして実行されています。これにより、アクティブプロセスリストに混乱が生じます。

したがって、私の質問は次のとおりです。既存のbashスクリプトから別のユーザーとして別のスクリプトを起動(フォーク)して、孤立した(スタンドアロン)プロセスのままにするにどうすればよいですか。

より詳細な説明:
私は基本的に、マシン上の他のユーザーに、.startUpと.shutDownという名前のホームディレクトリにあるそれぞれのサブディレクトリにある実行可能ファイルを実行することにより、システム起動またはシステムシャットダウン時に実行する手段を提供しようとしています。他の手段を見つけられなかったので、正確にそれを行うbashスクリプトを作成し、(スケルトンの例に従って)/etc/init.d/でサービススクリプトとして構成しました。 start引数を使用すると、.startUpディレクトリからすべてを起動し、stop引数を指定して実行すると、すべてのユーザーの.shutDownディレクトリからすべてを起動します。

あるいは、この問題を解決するために既存のソリューションを使用できたのかどうかにも興味があります。

更新
私は少し見て回ったところ、この質問を見つけました:https : //unix.stackexchange.com/questions/22478/detach-a-daemon-using-sudo

そこに受け入れられた答え、使用する:sudo -u user sh -c "daemon & disown %1"、私のために働く。しかし、私は%1否認せずに試しましたが、それは同じです。だからこれは私が期待したように私のために働くものです:

sudo -u <username> bash -c "<script_of_a_particular_user> &"

私の追加の質問は、なぜそれが否認せずに機能するのかということです。とにかく、何らかの潜在的な特別なケースのために、私はまだdisownコールを離れるべきですか?

更新2

どうやらこれも動作します:

su <username> -c "<script_of_a_particular_user> &"

この呼び出しとsudo呼び出しに違いはありますか?これは潜在的にまったく異なる質問であることを知っています。しかし、私はこのトピックのために自分で答えをここで見つけているので、誰かがこれをここで明確にすることができます。

更新3
suまたはsudoを使用したこれらのメソッドはどちらも、マシンの起動後に新しいstartparプロセス(rootとして実行される単一プロセス)を生成します。プロセスリストに次のように表示されます。

startpar -f -- <name_of_my_init.d_script>

なぜこのプロセスが生まれたのですか?他のinit.dスクリプトではこのプロセスが実行されていないため、明らかに私は何か間違ったことをしています。

更新4
startparの問題は解決されました。そのための別の質問を始めました
。rc.localまたはinit.dからプロセスを開始すると、startparプロセスがハングしたままになります。

また、非特権ユーザー向けの起動メカニズムについてさらに議論する別の質問:
通常のユーザー(非ルート)に初期化およびシャットダウン自動実行機能を提供する

回答:


18

これに対する正しい答えは、適切な「デーモン化」のために、標準入力、標準出力、および標準エラーを/ dev / null(または実際のファイル)にリダイレクトする必要があるということです。

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

SU -への代替ユーザーID someuserの
-c - SU引数が指定されたコマンドを実行する
nohupをする -ファイル名を指定して実行ハングアップへのコマンド免疫。親プロセスが子プロセスを終了するケースを防ぐため。念のためここに追加しました。しかし、実際には私の特定のケースでは効果がありません。必要かどうかは環境によって異なります(shoptを確認してください)
> / dev / null-標準出力を何にもリダイレクトせず、基本的に無効にします。
2>&1 -リダイレクト標準誤差ヌルにリダイレクトされ、標準出力(1)、(2)出力
-バックグラウンドに切り離し、これはには/ dev / nullに、標準入力をリダイレクトします。

これは基本的に、Debian dpkgのstart-stop-daemonユーティリティがそのコアで行うこととまったく同じです。そのため、コードに別の外部ユーティリティ呼び出しを導入するよりも、この方法でスクリプトを開始する方が好きです。start-stop-daemonは、起動する必要のある完全なデーモンプログラムがあり、start-stop-daemonが 提供する追加機能が必要な場合に役立ちます(たとえば、指定されたプロセスが既に実行されているかどうかを確認して、再度起動しないでください)。

また、たとえば/ dev / nullにリダイレクトする代わりに、プロセスのファイル記述子を閉じることもできます。

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0 <&-標準入力を閉じる(0)
1>&-標準出力を閉じる(1)
2>&-標準エラーを閉じる(2)出力

ファイル記述子番号が指定されている限り、<>記号の方向は重要ではありません。これも同様に良いことです:

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

または

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

ただし、方向が重要なstdinとstdoutの番号を使用せずに、それを書くための少し短い方法があります。

su someuser -c "some_script.sh <&- >&- 2>&- &" 

ファイル記述子が閉じられるか、/ dev / nullにリダイレクトされると(start-stop-daemonは/ dev / nullへのリダイレクトを実行します)、プロセスはデーモンとして安全にバックグラウンドで実行されます。そのため、起動時にスクリプトを起動する際の問題(startpar)を回避するために必要なものです。

最初のアイデアからソリューション全体を実装し、GitHubに配置しました:https :
//github.com/ivankovacevic/userspaceServices


Ivan、suまたはsu -loginを使用した方が良いですか?suの男を読みましたが、この特定のケースについては理解できません。
マッシモ

1
@Massimo、私の応答が遅れて申し訳ありません!この質問をチェックしてください:unix.stackexchange.com/questions/318572/…それを説明するより良いマニュアルページがあります。基本的に、違いは作業ディレクトリと環境変数の設定です。私はそれが実際に-login使用するのが好ましい選択肢かもしれません(別のユーザーとして何かをして)このようなユースケースのためだと思います
イワンKovacevic

3

このオプションを使用して、init.dからstart-stop-daemonを使用でき--userます。


私はミスターシャークの答え上のスタート・ストップ・デーモンについてコメントしていると私も私の答えと私の質問(更新4)へのアップデートを行った
イワンKovacevic

2

これを完全にはテストしていませんが、次のようなものだと思います。

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

起動時に

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

シャットダウンするとき。

.shutDownスクリプトの処理は、スタートアップのようなもので行うことができますが、とにかくシャットダウンが発生するため、スクリプトが終了することを確認することはできません:-)

トリックを行う必要があります。おそらく、いくつかの入力リダイレクトをスローする必要がありますが、ログファイルがいっぱいになることを心配する必要があります。


2
基本的に、これは機能します!start-stop-daemonは、ブート時またはその他の方法でプロセスを正常に起動できます。私はそれをテストしました。また、startparプロセスのハングに関する問題も取り除きます。ただし、開始呼び出しで--chuid USERも欠落しています。これがないと、プロセスがルートとして起動します。pidファイルはおそらく/ var / run /にも書き込まれるべきです。そうでない場合、ユーザーのホームディレクトリにルート所有のファイルが生成されます。しかし、私の考えでは、一般的なスクリプトの起動にはstart-stop-daemonが少しやり過ぎだと思われます。理由を詳しく説明しようとした答えを確認してください。
イヴァンコバセビッチ14

1

使ってみましたsuか?

su -c /home/user/.startUp/executable - user

-c suにコマンドを実行するように指示し、最後のパラメーターはコマンドを実行するユーザーです。


はい、動作しますが、引用符を付けてアンパサンドを追加します。そして、私はそれを次のように書くのがきれいだと思います:su <username> -c "/some/path/script.sh&"基本的に私はsudoを使用しました。 u <ユーザー名> bash -c "/some/path/script.sh&" ただし、これら2つに違いがあるかどうかはわかりません
イヴァンコバチェビッチ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.