12

ルートレベルのデーモンからセッションごとのGUIエージェントを開始/停止できる必要があります。

同様の問題がここここここで議論されています。

私がやりたいのは基本的に

for num in `ps ax | grep [s]bin/launchd | cut -c 1-5`; 
do 
    if [ $num -ne 1 ]; 
    then 
        sudo launchctl bsexec $num launchctl (un)load -S Aqua /Library/LaunchAgents/com.mycompany.mydaemon.plist; 
    fi; 
done

ただし、これは1つのインスタンスのみを開始/停止し、現在のGUIセッションでrootとして実行されます。sudoをオフにしておくと、開始します

task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right

bsexecの他のさまざまな順列をいじってみましたが(load / unloadコマンドを使用してbsexecからセカンダリスクリプトを呼び出すことを含む)、インスタンスをroot以外のものとして起動したり、別のGUIセッションで起動したりすることはできません。 。

私もとをいじってみましたが、そこでも運がsu - <user> ...ありsudo -u <user> ...ませんでした(多くの人が上記のリンクされた記事や他の場所で議論しているように)。

誰か考えがありますか?

編集:Graham Leeが以下に提案するように、ラッパーツールを使用してこれを実行しようとしましたが、次のエラーが発生します。

launch_msg(): Socket is not connected

これは、私が使用しているコマンドラインコマンド、ラッパー、およびスクリプトです(501はユーザーIDであり、63093はシステムにログインしている別のユーザーのlaunchdのpidです)。

コマンドライン:

sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent

ラッパー:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  if (argc != 3) {
    NSLog(@"Tool called with improper arguments");
    return -1;
  }

  int uid = [[NSString stringWithUTF8String:argv[1]] intValue];
  // TODO: REMOVE
  NSLog(@"Setting uid to |%i|", uid);

  setuid(uid);
  // TODO: REMOVE
  char *command = (char *)argv[2];
  NSLog(@"Executing command |%s|", command);
  system(command);

  [pool drain];
  return 0;
}

脚本:

/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist
4

4 に答える 4

6

使用launchctl bsexecは正しいですが、「実際の」エージェント実行可能ファイルを実行する前に、ターゲットユーザーにUIDをドロップするラッパーツールを起動する必要があります。ああ、そしてプロセスを探す方がおそらく良いでしょう。なぜならloginwindow、それらはログインセッションのリーダーだからです(ただし、プロセスも機能するlaunchd可能性が非常に高いです)。

于 2009-07-09T21:55:12.720 に答える
4

ユーザーごとのlaunchdインスタンスは、ターミナルから起動されたlaunchctlと同じブートストラップ名前空間で実行されていないようです。

Dock.appをpidドナーおよびsudoマジックとして使用することにより:

ps aux | grep Dock.app | grep -v grep | awk '{system("sudo launchctl bsexec "$2" sudo -u "$1" launchctl load -S Aqua /Library/LaunchAgents/com.my.agent.plist")}'

実行中のすべてのセッションでエージェントを起動することができます。

きちんとしたものではありませんが、機能します。

更新:10.7では動作しません。はい、エージェントが起動されますが、テストからわかるように、正しいコンテキストではありません。

于 2011-05-28T19:06:07.417 に答える
3

ここでの議論とこのスクリプトに基づいて、ラッパーツールは必要ないと思いました。これらの2つのbashスクリプトは、他の人にも役立つ可能性があります。

エージェントをアンロードします

#!/bin/bash
for id in `ps aux | grep -v grep | grep MyAgent | awk {'print $2'}`
do
    launchctl bsexec $id launchctl unload /Library/LaunchAgents/myAgent.plist
done

'MyAgent'を起動エージェントの名前に置き換えます。

ロードエージェント

#!/bin/bash
for pid_uid in $(ps -axo pid,uid,args | grep -i "[l]oginwindow.app" | awk '{print $1 "," $2}'); do

    pid=$(echo $pid_uid | cut -d, -f1)
    uid=$(echo $pid_uid | cut -d, -f2)

    launchctl bsexec "$pid" chroot -u "$uid" / launchctl load /Library/LaunchAgents/myAgent.plist
done

ルートデーモンから呼び出され、ログインしているすべてのユーザーのmyAgent.plistで参照されているLaunchAgentをロードおよびアンロードします。

OS X El Capitan(10.11)の「rootless」により、bsexecの使用が機能しなくなる可能性がありますが、10.10までは問題ないはずです。

于 2015-07-21T09:00:24.833 に答える
1

私も同じ問題を抱えていました。これを解決するには、launchdされたプロセスのpidが開始されたpid"under"launchdを使用します。

'launchctl bsexec'にコミットするpidは、適切なブートストラップを見つけるために使用されます。ルートlaunchdブートストラップで作業するよりも(ユーザーコンテキストから)launchdのpidを使用する場合。peを使用する場合。ユーザーのFinderまたはDockpidの場合、この「ユーザーごとの」ブートストラップで作業できます。

于 2014-09-02T09:40:03.863 に答える