LoginSignup
0
0

bashでwhile無限ループをバックグラウンド実行した際にプロセスが残り続ける

Last updated at Posted at 2024-04-27

結論(コメントを受け追記)

shopt huponxitがoffの状態で、バックグラウンド実行したプロセスは、ログアウトしても動き続けるのがbashの仕様。
onにしていると、ログアウト時にSIGHUPが送信され、プロセスは終了する。

状況

$ ps axj
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
      0       1       1       1 ?             -1 Ss       0   2:16 /lib/systemd/systemd --system --deserialize 63
      1       2       0       0 ?             -1 Sl       0   0:00 /init
      2   68672   68672   68672 ?             -1 Ss       0   0:00 /init
      :
  68672   68674   68672   68672 ?             -1 R        0   0:00 /init
  68674   68676   68676   68676 pts/3      69672 Ss    1000   0:00 -bash
  68676   69122   69122   68676 pts/3      69672 T     1000   0:01 vim public/newArticle006.md
  67817   69667   67817   67747 ?             -1 S        0   0:00 sleep 5
  68676   69672   69672   68676 pts/3      69672 R+    1000   0:00 ps axj

おや、なんだこのsleep 5は。
PIDを指定してkillしても何度でも実行される。
さては、無限ループで実行したプロセスが残っている…?

もうちょっと詳しく

$ ps axjf
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
   :
      1   65255   65253   65253 ?             -1 S        0   0:00 /init
  65255   67817   67817   67747 ?             -1 S        0   0:00  \_ -bash
  67817   70096   67817   67747 ?             -1 S        0   0:00      \_ sleep 5

PID 67817(bash)から、sleep 5が実行されている様子がわかる。
また、時間経過に伴い、sleep 5のPIDは変化していく。
sleep 5が定期実行されているのは間違いなさそうだが、何を5秒周期に実行したかったのだろう?
bashでは、while内の処理が子プロセスになるらしい(*1)し、上記のプロセスツリーを見ても、そうなっている様子。 →完全に理解が間違ってる。@ko1nksmさんがコメントで指摘くださった。自分なりの理解を記述した(#いただいたコメントについて
ということは、親プロセスにアタッチして、状況を確認できないか?

straceを使い、システムコールを見てみる。-fオプションで、子プロセスについてもトレースできる。
参考までに実行結果を記載する。

$ sudo strace -p 67817 -f
strace: Process 67817 attached
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 72713
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=0x55dfc4879e40, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=72713, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7fffd081fe50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, [INT TERM CHLD], [], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 72738 attached
 <unfinished ...>
[pid 72738] set_robust_list(0x7fd3fc362a20, 24 <unfinished ...>
[pid 67817] <... clone resumed>, child_tidptr=0x7fd3fc362a10) = 72738
[pid 72738] <... set_robust_list resumed>) = 0
[pid 67817] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid 72738] getpid( <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid 72738] <... getpid resumed>)       = 72738
[pid 72738] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 67817] rt_sigprocmask(SIG_BLOCK, [CHLD],  <unfinished ...>
[pid 72738] rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>[], 8) = 0
[pid 72738] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid 72738] rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid 72738] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigprocmask(SIG_BLOCK, [CHLD],  <unfinished ...>
[pid 72738] rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>[], 8) = 0
[pid 72738] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigaction(SIGINT, {sa_handler=0x55dfc4879e40, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 72738] rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72738] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] wait4(-1,  <unfinished ...>
[pid 72738] rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72738] rt_sigaction(SIGTERM, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72738] rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fd3fc3a7520}, {sa_handler=0x55dfc4877d70, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72738] execve("/usr/bin/date", ["date"], 0x55dfc54c8220 /* 26 vars */) = 0
[pid 72738] brk(NULL)                   = 0x560596bc3000
[pid 72738] arch_prctl(0x3001 /* ARCH_??? */, 0x7fffb8ea9b00) = -1 EINVAL (Invalid argument)
[pid 72738] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f86edbe5000
[pid 72738] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 72738] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=20915, ...}, AT_EMPTY_PATH) = 0
[pid 72738] mmap(NULL, 20915, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f86edbdf000
[pid 72738] close(3)                    = 0
[pid 72738] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[pid 72738] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\2\0\0\0\0\0"..., 832) = 832
[pid 72738] pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
[pid 72738] pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
[pid 72738] pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\226 \25\252\235\23<l\274\3731\3540\5\226\327"..., 68, 896) = 68
[pid 72738] newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2220400, ...}, AT_EMPTY_PATH) = 0
[pid 72738] pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
[pid 72738] mmap(NULL, 2264656, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f86ed9b6000
[pid 72738] mprotect(0x7f86ed9de000, 2023424, PROT_NONE) = 0
[pid 72738] mmap(0x7f86ed9de000, 1658880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x7f86ed9de000
[pid 72738] mmap(0x7f86edb73000, 360448, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7f86edb73000
[pid 72738] mmap(0x7f86edbcc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x215000) = 0x7f86edbcc000
[pid 72738] mmap(0x7f86edbd2000, 52816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f86edbd2000
[pid 72738] close(3)                    = 0
[pid 72738] mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f86ed9b3000
[pid 72738] arch_prctl(ARCH_SET_FS, 0x7f86ed9b3740) = 0
[pid 72738] set_tid_address(0x7f86ed9b3a10) = 72738
[pid 72738] set_robust_list(0x7f86ed9b3a20, 24) = 0
[pid 72738] rseq(0x7f86ed9b40e0, 0x20, 0, 0x53053053) = 0
[pid 72738] mprotect(0x7f86edbcc000, 16384, PROT_READ) = 0
[pid 72738] mprotect(0x5605963be000, 4096, PROT_READ) = 0
[pid 72738] mprotect(0x7f86edc1f000, 8192, PROT_READ) = 0
[pid 72738] prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
[pid 72738] munmap(0x7f86edbdf000, 20915) = 0
[pid 72738] getrandom("\x62\x24\x26\x90\xc2\x02\x25\x42", 8, GRND_NONBLOCK) = 8
[pid 72738] brk(NULL)                   = 0x560596bc3000
[pid 72738] brk(0x560596be4000)         = 0x560596be4000
[pid 72738] openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
[pid 72738] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2189040, ...}, AT_EMPTY_PATH) = 0
[pid 72738] mmap(NULL, 2189040, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f86ed79c000
[pid 72738] close(3)                    = 0
[pid 72738] openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
[pid 72738] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=309, ...}, AT_EMPTY_PATH) = 0
[pid 72738] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=309, ...}, AT_EMPTY_PATH) = 0
[pid 72738] read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0"..., 4096) = 309
[pid 72738] lseek(3, -176, SEEK_CUR)    = 133
[pid 72738] read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0"..., 4096) = 176
[pid 72738] close(3)                    = 0
[pid 72738] newfstatat(1, "", {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x2), ...}, AT_EMPTY_PATH) = 0
[pid 72738] write(1, "2024\345\271\264  4\346\234\210 22\346\227\245 \346\234\210\346\233\234\346\227\245 13"..., 43) = -1 EIO (Input/output error)
[pid 72738] close(1)                    = 0
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 1
[pid 72738] newfstatat(1, "", {st_mode=S_IFREG|0644, st_size=2996, ...}, AT_EMPTY_PATH) = 0
[pid 72738] read(1, "# Locale name alias data base.\n#"..., 4096) = 2996
[pid 72738] read(1, "", 4096)           = 0
[pid 72738] close(1)                    = 0
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja_JP.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja_JP.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja_JP/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale/ja/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja_JP.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja_JP.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja_JP/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] openat(AT_FDCWD, "/usr/share/locale-langpack/ja/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 72738] write(2, "date: ", 6)       = -1 EIO (Input/output error)
[pid 72738] write(2, "write error", 11) = -1 EIO (Input/output error)
[pid 72738] write(2, "\n", 1)           = -1 EIO (Input/output error)
[pid 72738] exit_group(1)               = ?
[pid 72738] +++ exited with 1 +++
<... wait4 resumed>[{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 72738
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=0x55dfc4879e40, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=72738, si_uid=0, si_status=1, si_utime=0, si_stime=1} ---
wait4(-1, 0x7fffd081fe50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, [INT TERM CHLD], [], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 72740 attached
 <unfinished ...>
[pid 72740] set_robust_list(0x7fd3fc362a20, 24 <unfinished ...>
[pid 67817] <... clone resumed>, child_tidptr=0x7fd3fc362a10) = 72740
[pid 72740] <... set_robust_list resumed>) = 0
[pid 67817] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid 72740] getpid( <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid 72740] <... getpid resumed>)       = 72740
[pid 72740] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid 67817] rt_sigprocmask(SIG_BLOCK, [CHLD],  <unfinished ...>
[pid 72740] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid 72740] rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>[], 8) = 0
[pid 72740] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid 72740] rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid 72740] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigprocmask(SIG_BLOCK, [CHLD],  <unfinished ...>
[pid 72740] rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigprocmask resumed>[], 8) = 0
[pid 72740] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] rt_sigaction(SIGINT, {sa_handler=0x55dfc4879e40, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 72740] rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520},  <unfinished ...>
[pid 67817] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72740] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 67817] wait4(-1,  <unfinished ...>
[pid 72740] rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72740] rt_sigaction(SIGTERM, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72740] rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fd3fc3a7520}, {sa_handler=0x55dfc4877d70, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fd3fc3a7520}, 8) = 0
[pid 72740] execve("/usr/bin/sleep", ["sleep", "5"], 0x55dfc54c8220 /* 26 vars */) = 0
[pid 72740] brk(NULL)                   = 0x562b0862a000
[pid 72740] arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd43bada40) = -1 EINVAL (Invalid argument)
[pid 72740] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8915827000
[pid 72740] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[pid 72740] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 72740] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=20915, ...}, AT_EMPTY_PATH) = 0
[pid 72740] mmap(NULL, 20915, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8915821000
[pid 72740] close(3)                    = 0
[pid 72740] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[pid 72740] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\2\0\0\0\0\0"..., 832) = 832
[pid 72740] pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
[pid 72740] pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
[pid 72740] pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\226 \25\252\235\23<l\274\3731\3540\5\226\327"..., 68, 896) = 68
[pid 72740] newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2220400, ...}, AT_EMPTY_PATH) = 0
[pid 72740] pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
[pid 72740] mmap(NULL, 2264656, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f89155f8000
[pid 72740] mprotect(0x7f8915620000, 2023424, PROT_NONE) = 0
[pid 72740] mmap(0x7f8915620000, 1658880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x7f8915620000
[pid 72740] mmap(0x7f89157b5000, 360448, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7f89157b5000
[pid 72740] mmap(0x7f891580e000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x215000) = 0x7f891580e000
[pid 72740] mmap(0x7f8915814000, 52816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8915814000
[pid 72740] close(3)                    = 0
[pid 72740] mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f89155f5000
[pid 72740] arch_prctl(ARCH_SET_FS, 0x7f89155f5740) = 0
[pid 72740] set_tid_address(0x7f89155f5a10) = 72740
[pid 72740] set_robust_list(0x7f89155f5a20, 24) = 0
[pid 72740] rseq(0x7f89155f60e0, 0x20, 0, 0x53053053) = 0
[pid 72740] mprotect(0x7f891580e000, 16384, PROT_READ) = 0
[pid 72740] mprotect(0x562b078ed000, 4096, PROT_READ) = 0
[pid 72740] mprotect(0x7f8915861000, 8192, PROT_READ) = 0
[pid 72740] prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
[pid 72740] munmap(0x7f8915821000, 20915) = 0
[pid 72740] getrandom("\x65\x08\xb7\xf9\xde\xdc\xbd\x48", 8, GRND_NONBLOCK) = 8
[pid 72740] brk(NULL)                   = 0x562b0862a000
[pid 72740] brk(0x562b0864b000)         = 0x562b0864b000
[pid 72740] openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
[pid 72740] newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2189040, ...}, AT_EMPTY_PATH) = 0
[pid 72740] mmap(NULL, 2189040, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f89153de000
[pid 72740] close(3)                    = 0
[pid 72740] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, ^Cstrace: Process 67817 detached
strace: Process 72740 detached
 <detached ...>

システムコールを全部追うのはしんどい。(私はそんなことできない)
子プロセスを生成しているってことだから、fork()したあとにexec()してるんだろうって目で見てみると...あった。
fork()ではなくclone()だったけど。

:
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 72738 attached
:
[pid 72738] execve("/usr/bin/date", ["date"], 0x55dfc54c8220 /* 26 vars */) = 0
:
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 72740 attached
:
[pid 72740] execve("/usr/bin/sleep", ["sleep", "5"], 0x55dfc54c8220 /* 26 vars */) = 0
:

なるほど、5秒ごとにdateを実行しているだけか。。。

正体

while true; do date; sleep 5; done &

&をつけてバックグラウンド実行しちゃうと、セッションを閉じてもプロセスが残り続けてしまう?
その仕組みについては把握できていない。時間があれば調べる。

→答えを教えていただきました。
冒頭の結論にも記載。

対処

不要な処理だと確認できたので、遠慮なくプロセスを落とす。

$ # kill <sleepコマンドのPPID(親プロセスID)>
$ kill 67817

いただいたコメントについて

while が必ず子プロセスになるわけではなくリンク先の記事で while が子プロセスになっている理由はパイプを使っているから

bashのmanページにも記載されていた。

   Pipelines
        :
       Each  command  in a pipeline is executed as a separate process (i.e., in a subshell).  See COMMAND EXECUTION ENVIRONMENT for a description of a subshell environment.  If the lastpipe option is enabled using the shopt builtin
       (see the description of shopt below), the last element of a pipeline may be run by the shell process.

が、処理のメカニズムがわからない。ちゃんと勉強したいと思った。
次に示す例から分かるように、プロセスが3つ動いていることは分かるけれど、ちゃんと分かっていない。

sample.sh
#!/bin/bash
echo -e "apple\nbanana\ncherry" | while read fruit; do
    echo $fruit
done
 $ strace -ff -o s_sample ./sample.sh
apple
banana
cherry
 $ ls
s_sample.21239  s_sample.21240  s_sample.21241  sample.sh*

1つ目は/bin/bash ./sample.sh。スクリプトを読み、パイプを作成、子プロセスをclone()で生成(fork()じゃないのはきっと、パイプ作成時に作成したfdを子プロセスと共有したいから)、子プロセスの終了を待つ。
2つ目はecho -e "apple\nbanana\ncherry"。出力をパイプに渡せるよう、dup2()でfdを複製してからwrite()で出力。
3つ目はwhile ~。2つ目同様、dup2()で入力用のfdを複製してからread()で受け取り、write()で出力。
分からないのは、bashがどのようにしてシステムコールを組み立てているのかという、bashの挙動そのもの。パイプの前後のコマンドでfdの扱いが違うけれどもどう制御しているのかとか、while ~って何?clone()されたからbashプロセスなんだろうが、親プロセスとは違う動作をするわけで、どういう仕組みなんだろう、とか。
疑問を呈してばかりいても仕方ないので、別途整理・理解したい。

またsleepコマンドは子プロセスになりますが外部コマンドだからであって

言われてみると、当然でした…
今のプロセス(bash)から実行されたプロセス(sleep)が、子プロセスになるのは当然ですね…

バックグラウンドでプロセスを実行している時にログアウトしてもプロセスが残るのはbashの仕様です。shopt -s huponexit を有効にすれば終了するようになります。

勉強になりました。
確かにhuponexitが無効になっていて、有効にするとログアウト時にプロセスが残らないことも確認できた。

 $ shopt | grep huponexit
huponexit       off

一応manページの抜粋をば。

SIGNALS
        :
       If  the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an interactive
       login shell exits.
:
SHELL BUILTIN COMMANDS
        :
       shopt [-pqsu] [-o] [optname ...]
               :
              huponexit
                      If set, bash will send SIGHUP to all jobs when an interactive login shell exits.

個人的には、huponexitは有効にしておいて、意図的にバックグラウンド実行したいときはnohupで…
って思ったけど、whileループで回そうと思うと、新しいシェルで実行しないといけないのかな。(この例だとdateの出力がnohup.outに吐かれるし、そもそもの例としてイマイチ)

 $ nohup while true; do date; sleep 5; done
-bash: syntax error near unexpected token `do'
 $ nohup bash -c 'while true; do date; sleep 5; done' &
[1] 17573
nohup: ignoring input and appending output to 'nohup.out'

参考

*1 https://alligatorswamp.hatenablog.com/entry/2012/07/25/211144

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0