ã¬ãããããã®æ£®è¥%ä»äºç´ãã¢ã¼ã ã§ãã
ç«ã¯æå¤ã¨è´ãé·ãã®ã§ãããã®è¨äºã¨ã¯ãã¾ãé¢ä¿ããã¾ããã
RHEL7ã¨RHEL8ã§åä½ãéãcat
çªç¶ã§ãã以ä¸ã®2è¡ãRHEL 7ã¨RHEL 8ã§å®è¡ããã¨åä½ã«éããããã¾ããã©ããªãã§ãããã?
$ echo test > hoge $ cat < hoge >> hoge
ãããã¯ãããã以ä¸ã®ããã«ãªãã¾ãã
- RHEL 7: ç¡éã«ã¼ãã«ãªã£ã¦ Ctrl-Cãªã©ã§åæ¢ãããã¾ã§æ¢ã¾ããªããããã¦ãã¡ã¤ã«hogeã«ã¯ã©ãã©ã'test\n' ã追è¨ããã¦ããã
- RHEL 8:
cat: -: input file is output file
ã¨ã¨ã©ã¼ãåºåããã¦catã忢ããã¡ã¤ã«hogeã¯å¤åããªãã
ä½ãèµ·ãã¦ããã®ã? (shellç·¨)
ããããã¯RHEL 8 ã®ç°å¢ã§ cat < hoge >> hoge
ãå®è¡ããã¨ãã«ä½ãèµ·ãã£ã¦ããã®ãã詳ããã¿ã¦ããã¾ãããã
観å¯ãããããã·ã§ã«ã®PIDã確èªããå¥ã®ã·ã§ã«ã§straceãåããã¾ãããã¡ã¤ã«ãæºåãã¦ããæ§åãã¿ããã®ã§ã ãã¡ã¤ã«é¢é£ã®ã·ã¹ãã ã³ã¼ã«ã ãã表示ããããã«-e file ãªãã·ã§ã³ãã¤ãã¦ãã£ã«ã¿ãã¾ãã
[観å¯å¯¾è±¡ã®sh] $ echo $$ 14340
[使¥ç¨ã®sh] $ strace -p 14340 -e file -f
æºåãã§ããã®ã§ã観å¯å¯¾è±¡ã®ã·ã§ã«ã§ãµããã³ cat < hoge >> hoge
ãå®è¡ãã¾ããstraceãä»è¾¼ãã æ¹ã«ã¯ä»¥ä¸ã®åºåãã§ã¦ãã¾ããã
strace: Process 14340 attached strace: Process 14911 attached [pid 14911] openat(AT_FDCWD, "hoge", O_RDONLY) = 4 [pid 14911] openat(AT_FDCWD, "hoge", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4 [pid 14911] execve("/usr/bin/cat", ["cat"], 0x55c4fc2d96c0 /* 41 vars */) = 0 (以ä¸ç¥)
shãã³ãã³ãcatãå®è¡ããã«ããããã¾ãforkã§ããã»ã¹14911ã使ããããã§ãã¡ã¤ã« "hoge" ã2åopen ãã¾ãã1åã¯æ¨æºå ¥å(stdin)ã®ããã«ãèªã¿è¾¼ã¿å°ç¨(O_RDONLY)ã§ããã1ã¤ã¯æ¨æºåºå(stdout)ã¨ãã¦ãæ¸ãè¾¼ã¿å°ç¨(O_WRONLY)ãã¤è¿½è¨(O_APPEND)ã§éãã¦ãã¾ãã ã·ã§ã«ããã¡ã¤ã«ãç¨æãã¦ç°å¢ãã¨ã¨ã®ã£ãã®ã§execveã§catãå®è¡ãã¾ãã
ããã¾ã§ã®åä½ã¯RHEL 7ã§ãåãã§ãã
ä½ãèµ·ãã¦ããã®ã? (catç·¨)
ããããcatã®å®è¡ãã¯ãã¾ãã¾ããä»åã¯æç¢ºãªã¨ã©ã¼ã¡ãã»ã¼ã¸ãåºåããã¦ããã®ã§ã½ã¼ã¹ã®ä¸ã§ã¡ãã»ã¼ã¸ãæ¢ãã¾ãã
RHEL8ã® coreutils 8.30å cat.c ãã
690 691 /* Don't copy a nonempty regular file to itself, as that would 692 merely exhaust the output device. It's better to catch this 693 error earlier rather than later. */ 694 695 if (out_isreg 696 && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino 697 && lseek (input_desc, 0, SEEK_CUR) < stat_buf.st_size) 698 { 699 error (0, 0, _("%s: input file is output file"), quotef (infile)); 700 ok = false; 701 goto contin; 702 } 703
stat_bufã¯å ¥åãã¡ã¤ã«ã«å¯¾ãã¦statãè¡ã£ãçµæã§ãã
- åºåå ã®ãã¡ã¤ã«ãpipeãsocketã§ã¯ãªãé常ã®ãã¡ã¤ã«ã§
- åºåãã¡ã¤ã«ã¨æ¯è¼ãã¦ããã¤ã¹ã¨inodeçªå·ãåã(ã¤ã¾ãåããã¡ã¤ã«å®ä½ãæã)ã§ãã¤
- å ¥åå´ã®ç¾å¨ä½ç½®ãããã¨ã«ãã¼ã¿ãåå¨ãã
ã®3ã¤ãæç«ããå ´åãRHEL 7ã®æã®åä½ã¨ãã¦èª¬æããããã«ç¡éã«ãã¡ã¤ã«ã伸ã³ã¤ã¥ãã¦ãã¾ã(ãã®çµæãªã½ã¼ã¹ãæ¯æ¸ãã)ã®ã§ãããã¨ã©ã¼ã¨ãã¦æ©ãã«åæ¢ãããã¨ããã³ã¼ããæ¸ããã¦ãã¾ãã
ãªãã»ã©äºæ 鲿¢ã®æå³ã¯ãããã¾ãããRHEL 7ã®catã«ã¯ãã®ãã§ãã¯ã¯åå¨ããªãã£ãã®ã§ããããâ¦â¦? 該å½ããç®æãã¿ã¦ã¿ã¾ãããã
RHEL 7ã® coreutils 8.22å cat.c ãã
707 /* Compare the device and i-node numbers of this input file with 708 the corresponding values of the (output file associated with) 709 stdout, and skip this input file if they coincide. Input 710 files cannot be redirected to themselves. */ 711 712 if (check_redirection 713 && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino 714 && (input_desc != STDIN_FILENO)) 715 { 716 error (0, 0, _("%s: input file is output file"), infile); 717 ok = false; 718 goto contin; 719 }
ããããåããããªæå³ã®ã³ã¼ããããã®ã§ãããå°ãã¨ã©ã¼æ¤åºã®æ¡ä»¶ãçããå ¥åãã¡ã¤ã«ãæ¨æºå ¥åã§ããã°è¦éããã¦ãã¾ãããã§ãã
確èª
çè§£ãæ£ããã確èªãããããRHEL 7ã§ä»¥ä¸ã®ã³ãã³ãã§æ£ããã¨ã©ã¼æ¤åºãããããã¨ã確èªãã¾ãã
$ cat hoge >> hoge cat: hoge: input file is output file
ç¡éã«é·ããªãç«ã¯å¥½ã¾ããªãã¨ãã話ã§ããã