質問するログイン新規登録
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

832閲覧

Linux sudoで実行したプログラムからsudoのpidを取得したい

nryk

総合スコア2

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

1グッド

0クリップ

投稿2025/07/19 14:30

編集2025/07/22 15:40

1

0

実現したいこと

Linux初学者です。プログラムをsudo権限でバックグラウンド実行した時に表示されるPIDと、プログラム内でgetpid()するPIDと一致させたいです。

上記「プログラム」は下記をコンパイルしたものです。

C

1//cpu_hog.c 2 3#include <stdio.h> 4#include <unistd.h> 5 6int main(void) 7{ 8 printf("PID: <%d>\n", getpid()); 9 fflush(stdout); 10 return 0; 11}

補足:事象が再現する最小限のコードを貼り付けています。元々やろうとしていた事(この疑問を持ったきっかけ)については備考欄に記載しています。

発生している問題・分からないこと

shell

1$ gcc -O0 cpu_hog.c 2$ taskset -c 0 nice -n 19 ./a.out & sudo taskset -c 0 nice -n -10 ./a.out & 3[7] 66596 4[8] 66597 5$ 6PID: <66596> 7PID: <66600> 8 9[7] Done taskset -c 0 nice -n 19 ./a.out 10[8] Done sudo taskset -c 0 nice -n -10 ./a.out 11$

sudoで実行しない場合、[7] 66596, PID: <66596>のように2つのPIDが一致しています。
しかしsudoで実行した方のプロセスは[8] 66597, PID: <66600>のように異なるPIDが表示されています。これについて何点か質問したいです。

質問①そもそも上記の事象が起こる原因

melian様からのコメントで解決済み
基本的なことは勉強した結果、下記のように考えました。あっているでしょうか?

  • tasksetおよびniceは、内部でclone,forkせずにexecしているためPIDが同じになる
  • sudoは内部でfork cloneしてからexecしているのでPIDが異なる

質問② PIDを一致させる方法

上記のshell出力において、[8] 66597sudoのpid、PID: <66600>a.outのpidという認識です。これを一致させるにはどうしたらいいでしょうか?(質問タイトルには両方sudoのPIDにしたいと書いていますが、一致すればどちらでもいいです)

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

一旦sudo無しの方は無視して、sudoありの方だけPIDを一致させようと考えました。
a.outの親プロセスのpidを見ればsudoのpidがわかるかと思い、cpu_hog.cgetpidgetppidに変更してみました。その結果がこれです。

$ taskset -c 0 nice -n 19 ./a.out & sudo taskset -c 0 nice -n -10 ./a.out & [10] 75810 [11] 75811 PID: <1799> PID: <75813> $ [10] Done taskset -c 0 nice -n 19 ./a.out [11] Done sudo taskset -c 0 nice -n -10 ./a.out

[10](sudo無し)の方については、bashのPID1799が出力されており、想定通りの動きです。
しかし[11](sudoあり)の方は余計にわからなくなってしまいました。[11] 75811PID: <75813>という異なるPIDが表示されていますが、これはそれぞれ何のPIDなのでしょうか。

補足①バージョン情報

shell

1$ lsb_release -a 2No LSB modules are available. 3Distributor ID: Ubuntu 4Description: Ubuntu 24.04.2 LTS 5Release: 24.04 6Codename: noble 7 8$ gcc --version 9gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 10Copyright (C) 2023 Free Software Foundation, Inc. 11This is free software; see the source for copying conditions. There is NO 12warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14$ dpkg -l | grep libc6 15ii libc6:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: Shared libraries 16ii libc6-dbg:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: detached debugging symbols 17ii libc6-dev:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: Development Libraries and Header Files

補足②

教えていただいた内容を盛り込んで更新しました
元々はプロセスの優先順位と実行時間の関係を観察しようとしていました。質問内容には直接関係ありませんが、一応元のコードも貼り付けておきます。

C

1#include <stdio.h> 2#include <unistd.h> 3#include <time.h> 4#include <sys/time.h> 5#include <libproc2/pids.h> 6#include <string.h> 7 8int main(void) 9{ 10 struct pids_info *info = NULL; 11 enum pids_item item[] = {PIDS_ID_PPID, PIDS_CMD}; 12 procps_pids_new(&info, item, 2); // 第3引数はitem[]の要素数 13 14 pid_t ppid = getppid(); 15 struct pids_fetch *pidread = procps_pids_select(info, (unsigned int *)&ppid, 1, PIDS_SELECT_PID); 16 17 pid_t pppid = pidread->stacks[0]->head[0].result.u_int; 18 char *pppcmd = pidread->stacks[0]->head[1].result.str; 19 20 clock_t start = clock(); 21 22 // 実時間の開始(リアルタイム時計) 23 struct timeval real_start, real_end; 24 gettimeofday(&real_start, NULL); 25 26 volatile unsigned long long count = 0; 27 for (unsigned long long i = 0; i < 5000000000ULL; i++) 28 { 29 count += i; 30 } 31 32 clock_t end = clock(); 33 34 // 実時間の終了 35 gettimeofday(&real_end, NULL); 36 37 double elapsed = (double)(end - start) / CLOCKS_PER_SEC; 38 39 double real_time = (real_end.tv_sec - real_start.tv_sec) + (real_end.tv_usec - real_start.tv_usec) / 1000000.0; 40 41 pid_t disp = (strcmp(pppcmd, "sudo") == 0) ? pppid : getpid(); 42 printf("\n<%d>Done. CPU time: %.2f seconds Real time: %.2f sec", disp, elapsed, real_time); 43 fflush(stdout); 44 return 0; 45}

追記 double cloneの詳細

ご参考までに、手元でdouble cloneが発生したソースコードとコンソール出力を貼り付けておきます。環境については「補足①バージョン情報」に掲載しています。

C

1//check_pid.c 2#include <stdio.h> 3#include <unistd.h> 4#include <stdlib.h> 5#include <libproc2/pids.h> 6#include <string.h> 7 8int main(void) 9{ 10 struct pids_info *info = NULL; 11 enum pids_item item[] = {PIDS_ID_PPID, PIDS_CMD}; 12 procps_pids_new(&info, item, 2); 13 14 pid_t ppid = getppid(); 15 struct pids_fetch *pidread = NULL; 16 pidread = procps_pids_select(info, (unsigned int *)&ppid, 1, PIDS_SELECT_PID); 17 printf("PID: <%d>\n", getpid()); 18 printf("PPID: <%d>\n", getppid()); 19 printf("PPPID: <%d>\n", pidread->stacks[0]->head[0].result.u_int); 20 printf("PPPCMD: <%s>\n", pidread->stacks[0]->head[1].result.str); 21 fflush(stdout); 22 system("ps afT"); 23 fflush(stdout); 24 25 return 0; 26}

shell

1$ gcc -O0 -Wall -Wextra check_pid.c -lproc2 2$ sudo ./a.out & 3[1] 3952 4$ 5PID: <3955> 6PPID: <3954> 7PPPID: <3952> 8PPPCMD: <sudo> 9 PID TTY STAT TIME COMMAND 10 1715 pts/3 Ss+ 0:00 /bin/bash --init-file /home/user/.vscode-server/cli/servers/Stable-xxxxxxxxxxxxxxxxxxxxxxxx 11 3952 pts/3 S 0:00 \_ sudo ./a.out 12 3954 pts/4 Ss+ 0:00 \_ sudo ./a.out 13 3955 pts/4 S 0:00 \_ ./a.out 14 3956 pts/4 S 0:00 \_ sh -c -- ps afT 15 3957 pts/4 R 0:00 \_ ps afT 16 974 tty1 Ss+ 0:00 /sbin/agetty -o -p -- \u --noclear - linux 17 18[1]+ Done sudo ./a.out 19$
melian👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2025/07/19 19:27

手元の環境は Ubuntu 24.10/glibc 2.4.0 ですが、昨今では fork の代わりに clone システムコールが使用されます。 > fork(2) > Since glibc 2.3.3, rather than invoking the kernel's fork() system call, the glibc fork() wrapper that is provided as part of the NPTL threading implementation invokes clone(2) with flags that provide the same effect as the traditional system call. strace コマンドでシステムコール(exec* と clone)を表示してみます。 # execve(2) のみ $ strace -f -e /exec,/clone taskset -c 0 nice -n 19 ./a.out & execve("/usr/bin/taskset", ["taskset", "-c", "0", "nice", "-n", "19", "./a.out"], 0x7ffc8fc47f28 /* 79 vars */<alpha> /work/tmp/stack $ ) = 0 execve("/usr/bin/nice", ["nice", "-n", "19", "./a.out"], 0x7fff044d4d58 /* 79 vars */) = 0 execve("./a.out", ["./a.out"], 0x7ffde2f06600 /* 79 vars */) = 0 PID: <1222091> +++ exited with 0 +++ # sudo プロセスが clone(2) を使用して子プロセスを作成 $ sudo strace -f -e /exec,/clone sudo taskset -c 0 nice -n 19 ./a.out & execve("/usr/bin/sudo", ["sudo", "taskset", "-c", "0", "nice", "-n", "19", "./a.out"], 0x7fff5bd94910 /* 17 vars */) = 0 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7e8e22e99b10) = 1222123 strace: Process 1222123 attached [pid 1222123] clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7e8e22e99b10) = 1222124 strace: Process 1222124 attached [pid 1222124] execve("/usr/bin/taskset", ["taskset", "-c", "0", "nice", "-n", "19", "./a.out"], 0x652f9e8bea00 /* 17 vars */) = 0 [pid 1222124] execve("/usr/bin/nice", ["nice", "-n", "19", "./a.out"], 0x7ffc4b4ed128 /* 17 vars */) = 0 [pid 1222124] execve("./a.out", ["./a.out"], 0x7ffcc0104370 /* 17 vars */) = 0 [pid 1222124] +++ exited with 0 +++ [pid 1222123] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1222124, si_uid=0, si_status=0, si_utime=0, si_stime=0} --- PID: <1222124> [pid 1222123] +++ exited with 1 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1222123, si_uid=0, si_status=1, si_utime=0, si_stime=0} --- +++ exited with 0 +++ > 質問①そもそも上記の事象が起こる原因 > > * tasksetおよびniceは内部でexecしているためPIDが同じになる > * sudoは内部でforkしているのでPIDが異なる そうなります。(glibc 2.3.3 以降では fork ではなく clone になります) また、sudo(1) には以下の様に記載されています。 > sudo(1) > Process model > > If an I/O logging plugin is configured to log terminal I/O, or if the security policy explicitly requests it, a new pseudo-terminal ("pty") is allocated and fork(2) is used to create a second sudo process, referred to as the monitor. The monitor creates a new terminal session with itself as the leader and the pty as its controlling terminal, calls fork(2) again, sets up the execution environment as described above, and then uses the execve(2) system call to run the command in the child process.
nryk

2025/07/20 17:06

詳細にご回答ありがとうございました。自分の環境でもstraceして、似たような出力になっていることを確認できました。 追加で伺いたいのですが、`execve(2)`などの`2`は何を指すのでしょうか(`man 2 execve`の2?)
melian

2025/07/20 17:09

> `execve(2)`などの`2`は何を指すのでしょうか(`man 2 execve`の2?) はい、man のセクションナンバーになります。2 はシステムコール(Linuxカーネルが提供する関数)です。
nryk

2025/07/20 17:18

早速ご回答いただきありがとうございます。`strace`で自力で調べる方法をご教示いただき、大変参考になりました。
bsdfan

2025/07/21 00:02

> tasksetおよびniceは内部でexecしているためPIDが同じになる > sudoは内部でfork cloneしているのでPIDが異なる sudo も最終的には exec するので、fork(clone) してから exec するか、fork(clone) せずに exec するか、の違いと言った方がいいと思います。
nryk

2025/07/21 01:37

bsdfan様 コメントありがとうございます! 本文を修正いたしました。
guest

回答2

0

ベストアンサー

質問② PIDを一致させる方法

一旦sudo無しの方は無視して、sudoありの方だけPIDを一致させようと考えました。

しかし[11](sudoあり)の方は余計にわからなくなってしまいました。[11] 75811とPID: <75813>という異なるPIDが表示されていますが、これはそれぞれ何のPIDなのでしょうか。

質問のコメントにも書きましたが、sudo コマンドでは内部で2回の clone(2) が実行されています。(参考資料:UNIX daemonization and the double fork)

bash

1$ sudo strace -f -e /exec,/clone sudo taskset -c 0 nice -n 19 ./a.out & 2execve("/usr/bin/sudo", ["sudo", "taskset", "-c", "0", "nice", "-n", "19", "./a.out"], 0x7fff5bd94910 /* 17 vars */) = 0 3clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7e8e22e99b10) = 1222123 4strace: Process 1222123 attached 5[pid 1222123] clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7e8e22e99b10) = 1222124 6strace: Process 1222124 attached 7[pid 1222124] execve("/usr/bin/taskset", ["taskset", "-c", "0", "nice", "-n", "19", "./a.out"], 0x652f9e8bea00 /* 17 vars */) = 0 8[pid 1222124] execve("/usr/bin/nice", ["nice", "-n", "19", "./a.out"], 0x7ffc4b4ed128 /* 17 vars */) = 0 9[pid 1222124] execve("./a.out", ["./a.out"], 0x7ffcc0104370 /* 17 vars */) = 0 10[pid 1222124] +++ exited with 0 +++ 11[pid 1222123] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1222124, si_uid=0, si_status=0, si_utime=0, si_stime=0} --- 12PID: <1222124> 13[pid 1222123] +++ exited with 1 +++ 14--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1222123, si_uid=0, si_status=1, si_utime=0, si_stime=0} --- 15+++ exited with 0 +++

上記の動作から、「sudoありの方だけPIDを一致させる」場合には a.out プロセスの親プロセス(2回目のclone(2)で生成されるプロセス)の親プロセス(最初のclone(2)で生成されるプロセス)のPIDを取得する必要があります。具体的には procps(3) を利用します。

手元の環境は Ubuntu 24.10 なので、最初に libproc2 パッケージをインストールします。

bash

1$ sudo apt install libproc2-0 libproc2-dev

cpu_hog_sudo_version.c

c

1#include <stdio.h> 2#include <unistd.h> 3#include <libproc2/pids.h> 4 5int main(void) { 6 struct pids_info *info = NULL; 7 enum pids_item item[] = { PIDS_ID_PPID }; 8 procps_pids_new(&info, item, 1); 9 10 pid_t ppid = getppid(); 11 struct pids_fetch *pidread = NULL; 12 pidread = procps_pids_select(info, (unsigned int *)&ppid, 1, PIDS_SELECT_PID); 13 printf("PID: <%d>\n", pidread->stacks[0]->head->result.u_int); 14 fflush(stdout); 15 16 return 0; 17}

上記のソースコードをコンパイルして実行します。

bash

1$ gcc -O0 -Wall -Wextra cpu_hog_sudo_version.c -lproc2 2$ sudo taskset -c 0 nice -n 19 ./a.out & 3[1] 1275550 4$ PID: <1275550>

追記

一度にPIDS_ID_PPID, PIDS_CMDを取得できる方法があれば

その場合は itemPIDS_ID_PPIDPIDS_CMD を指定します。また、項目が2個になりますので procps_pids_new() の第3パラメータには 2 を指定します。
フェッチしたデータは pidread->stacks[0]->head[0]PIDS_ID_PPID に、pidread->stacks[0]->head[1]PIDS_CMD に対応しています。

c

1#include <stdio.h> 2#include <unistd.h> 3#include <stdlib.h> 4#include <libproc2/pids.h> 5#include <string.h> 6 7int main(void) 8{ 9 struct pids_info *info = NULL; 10 enum pids_item item[] = {PIDS_ID_PPID, PIDS_CMD}; 11 procps_pids_new(&info, item, 2); 12 13 pid_t ppid = getppid(); 14 struct pids_fetch *pidread = NULL; 15 pidread = procps_pids_select(info, (unsigned int *)&ppid, 1, PIDS_SELECT_PID); 16 printf("PID: <%d>\n", getpid()); 17 printf("PPID: <%d>\n", getppid()); 18 printf("PPPID: <%d>\n", pidread->stacks[0]->head[0].result.u_int); 19 printf("PPPCMD: <%s>\n", pidread->stacks[0]->head[1].result.str); 20 fflush(stdout); 21 22 return 0; 23}

投稿2025/07/20 19:03

編集2025/07/21 11:41
melian

総合スコア21343

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nryk

2025/07/21 11:04 編集

サンプルコードのご提示ありがとうございます。手元でも同じ出力を得ることができました。 あとはppidが指すプロセスがsudoかどうか確かめて分岐するだけなのですが、その部分についてもご教示いただいてもよろしいでしょうか。 自分なりにやってみたコードは質問本文の「追記(ppidが指すプログラムを取得)」に追記しています。 info1, info2というあまりに不恰好な実装なのですが、どうしてもこれ以外のやり方を見つけることができず、一度にPIDS_ID_PPID, PIDS_CMDを取得できる方法があればご教示いただけると幸いです。
melian

2025/07/21 11:41

一度にPIDS_ID_PPID, PIDS_CMDを取得できる方法に関して追記しました。
nryk

2025/07/21 14:18 編集

ありがとうございます!無事に今回やろうとしていた事全て実施できました。 最後にもう一つだけ伺いたいのですが、調べるときのコツとかってあるのでしょうか? 個人的に今回特に難関だったのが下記の2点です。 ・最初にご提示いただいたサンプルコードがなければ、procps_pidsの存在にすら気づけなかった ・`pidread`にPIDS_ID_PPID, PIDS_CMDを取得するところまでは何とかたどり着いたものの、その後head[1]にアクセスするという発想に至らず、結局"sudo"という文字列を取得できなかった(itemとheadの要素数が連動することに気付かなかった) 私自身多少はプログラミングの経験があるものの、ググって出てこなかったら詰み、サンプルコードがなければ詰み、ということが未だに多く、man等の一次情報を組み合わせて何かを作る際のコツがあればご教示いただけないかと思った次第です。 聞いてばかりで恐縮ですが、もし普段意識されている事があればご教示いただけないでしょうか。
melian

2025/07/21 16:33

> 調べるときのコツとかってあるのでしょうか? 今回の場合には当てはまりませんが、エラーメッセージが表示されているのであれば、その文言を検索するだけで解決に至ることがあります。または、対象のソフトウェアがGitHubで公開されているのであれば Issues で文言を検索することもあります。 ですが、proc2 ライブラリに関しては情報が少なく、そのため proc2 のソースコードリポジトリ(https://gitlab.com/procps-ng/procps)にある単体テスト用のコードを参考にしました。(リポジトリにサンプルコードが置かれている場合が多いのですが、proc2 では見当たりません) library/tests/test_pids.c · master · procps-ng / procps · GitLab https://gitlab.com/procps-ng/procps/-/blob/master/library/tests/test_pids.c > itemとheadの要素数が連動することに気付かなかった 私も当初は気付かずにいて、インクルードファイル(libproc2/pids.h)にある以下のマクロ定義で分かったことでした。 #define PIDS_VAL( relative_enum, type, stack, info ) \  stack -> head [ relative_enum ] . result . type > もし普段意識されている事があれば できるだけ公式サイトで提供されているマニュアルやドキュメントを参照する様にしています。稀にマニュアルがアップデートされていなくて、最新版と齟齬が生じている場合もあるのですが、その様な時はソースコードを読んで必要最低限な知識を得る様にしています。
otn

2025/07/21 16:34

参考資料として書かれているURLは「制御端末を持たないプロセスを作るには2回forkする」なのでsudoは関係ないと思います。 今使える範囲にubuntuはないですが、CentOS Stream と Debian だと、sudo で二重cloneは発生しないですね。違いの理由が分からない。melianさんの環境でもclone2回のようなのでnrykさんの環境固有ということではないわけですよね。 古い話では、昔のUnixだとコンソールからログインするとプロセスの親子関係は 「getty -> ログインシェル 」(gettyから起動されるloginは認証の後にforkせずログインシェルをexecveする)だったのが、今の少なくともLinuxだと「gettyの後継 -> login -> ログインシェル 」とloginがforkして居座るように変わりました。これの理由がPAMらしい(詳しく調べてないですが)ので、今回もPAM絡みかもしれません。
nryk

2025/07/22 01:45

>melian様 お返事いただきありがとうございます。 やはり公式のマニュアルを読むのが一番、という事ですね。 またソースコードは私も見たものの、マクロ定義には目がいかなかったので、次以降参考にしようと思います。 改めまして、ありがとうございました!!
nryk

2025/07/22 02:38

>otn様 他の環境についてはよくわからないのですが、参考までに手元で検証に使ったコードを「追記② double cloneの詳細」に掲載しました。
guest

0

fオプションをつけたpsを入れると理解しやすいと思います。

しかし11の方は余計にわからなくなってしまいました。[11] 75811とPID: <75813>という異なるPIDが表示されていますが、これはそれぞれ何のPIDなのでしょうか。

普通は、./a.outの親プロセスはsudoのはずです。sudo./a.outの間になにか挟まっているのでしょうね。ちょっと思いつきませんが、おそらくpsの結果からわかると思います。

C

1#include <stdio.h> 2#include <unistd.h> 3#include <stdlib.h> 4 5int main(void) 6{ 7 printf("PID: <%d> PPID: <%d>\n", getpid(), getppid()); 8 fflush(stdout); 9 system("ps afT"); 10 return 0; 11}

投稿2025/07/20 18:38

otn

総合スコア86387

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nryk

2025/07/21 03:35 編集

ご回答ありがとうございます。 上記のコードを動かしたところ、sudo...が2回呼ばれていて、シェル出力されるのは1回目のsudo...のPID、getppid()で取得できるのは2回目のsudo...のPIDであることがわかりました。 プログラム内からpsする方法もあったのですね、勉強になりました。ありがとうございます。 ```shell $ sudo taskset -c 0 nice -n 19 ./a.out & [1] 3311 $ PID: <3314> PPID: <3313> PID COMMAND 1928 /bin/bash ... 1476 /bin/bash ... 3311 \_ sudo taskset -c 0 nice -n 19 ./a.out 3313 \_ sudo taskset -c 0 nice -n 19 ./a.out 3314 \_ ./a.out 3315 \_ sh -c -- ps afT 3316 \_ ps afT 1335 /bin/bash ... 967 /sbin/agetty -o -p -- \u --noclear - linux [1]+ Done sudo taskset -c 0 nice -n 19 ./a.out ```
otn

2025/07/21 17:10 編集

> プログラム内からpsする方法もあったのですね、勉強になりました。ありがとうございます。 デバッグ用途なら system("~~"); で十分かと思います。 melianさんお書きのサブルーチンは知らなかったので、私なら /proc/PID/status か stat を直接見たと思います。ps で表示可能な範囲の情報は他ユーザーのプロセスのものでも見られるはず(実際にはpsはここを見てるはずなので話が逆ですが)。 status は冒頭がこんな感じです。Cでの処理ならstatがいいかも。 Name: sudo (コマンドライン全体は /proc/PID/cmdline に NUL セパレーターで入ってます) Umask: 0022 State: S (sleeping) Tgid: 1106243 Ngid: 0 Pid: 1106243 PPid: 1106222
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問