結論(コメントを受け追記)
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つ動いていることは分かるけれど、ちゃんと分かっていない。
#!/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