ºÎ·Ï D. I/O¿Í I/O ÀçÁöÇâ¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼Ò°³

Stephane Chazelas°¡ ÀÛ¼º, º» ¹®¼­ÀÇ ÀúÀÚ°¡ ±³Á¤

¾î¶² ¸í·É¾îµç óÀ½ ¼¼ °³ÀÇ ÆÄÀÏ µð½ºÅ©¸³ÅÍ°¡ »ç¿ë °¡´ÉÇϱ⸦ ±â´ëÇÕ´Ï´Ù. ù ¹ø°´Â Àбâ¿ëÀÎ fd 0(Ç¥ÁØÀÔ·Â)ÀÌ°í, ³ª¸ÓÁö µÑÀº ¾²±â¿ëÀ¸·Î fd 1°ú fd 2ÀÔ´Ï´Ù.

Ç¥ÁØÀÔ·Â(stdin), Ç¥ÁØÃâ·Â(stdout), Ç¥ÁØ¿¡·¯(stderr)´Â °¢ ¸í·É¾îµé°ú ¿¬°üÀÌ ÀÖ½À´Ï´Ù. ls 2>&1 Àº ls ¸í·É¾îÀÇ Ç¥ÁØ¿¡·¯¸¦ Àӽ÷Π½©ÀÇ Ç¥ÁØÃâ·Â°ú µ¿ÀÏÇÑ "¸®¼Ò½º"·Î ¿¬°á½ÃÄÑ ÁÝ´Ï´Ù.

°ü½ÀÀûÀ¸·Î ÇÑ ¸í·É¾î´Â fd 0 (Ç¥ÁØÀÔ·Â)¿¡¼­ ÀÔ·ÂÀ» Àаí, fd 1 (Ç¥ÁØÃâ·Â)À¸·Î º¸ÅëÀÇ °á°úµéÀ» Ãâ·ÂÇÏ°í, ¿¡·¯ Ãâ·ÂÀº fs 2 (Ç¥ÁØ¿¡·¯)·Î ÇÕ´Ï´Ù. ¸¸¾à¿¡ À̵éÁß Çϳª¶óµµ ¿­·Á ÀÖÁö ¾Ê´Ù¸é ¹®Á¦°¡ »ý±æÁöµµ ¸ð¸¨´Ï´Ù.

bash$ cat /etc/passwd >&-
cat: standard output: Bad file descriptor
      

¿¹¸¦ µé¾î, xtermÀ» ½ÇÇà½ÃÅ°¸é ¸ÕÀú ÀÚ½ÅÀ» ÃʱâÈ­ÇÏ°í »ç¿ëÀÚ ½©À» ¶ç¿ì±â Àü¿¡ Å͹̳Πµð¹ÙÀ̽º(/dev/pts/<n> ³ª ºñ½ÁÇÑ°Í)¸¦ ¼¼ ¹ø ¿±´Ï´Ù.

ÀÌ ½ÃÁ¡¿¡¼­ Bash ´Â ÀÌ ¼¼ °³ÀÇ ÆÄÀÏ µð½ºÅ©¸³Å͵éÀ» »ó¼Ó¹Þ°í Bash ¿¡¼­ ½ÇÇà½ÃÅ°´Â °¢°¢ÀÇ ¸í·É¾î(ÀÚ½Ä ÇÁ·Î¼¼½º)µéÀº ´Ù½Ã Â÷·Ê´ë·Î ÀÌ µð½ºÅ©¸³Å͵éÀ» »ó¼Ó¹Þ½À´Ï´Ù. ÀçÁöÇâÀ̶õ ÀÌ ÆÄÀÏ µð½ºÅ©¸³ÅÍÁßÀÇ Çϳª¸¦ ´Ù¸¥ ÆÄÀÏ(ȤÀº ÆÄÀÌÇÁ³ª »ç¿ë °¡´ÉÇÑ ¸ðµç °Í)·Î ÀçÇÒ´ç ½ÃÅ°´Â °ÍÀÔ´Ï´Ù. ÆÄÀÏ µð½ºÅ©¸³ÅÍ´Â Áö¿ªÀû(locally)À¸·Î ÀçÇÒ´ç µÉ ¼öµµ ÀÖ°í(¸í·É¾î, ¸í·É¾î ±×·ì, ¼­ºê½©, while, if, case, for ·çÇÁ µîÀ» À§Çؼ­), ½©ÀÇ ³ª¸ÓÁö ºÎºÐÀ» À§Çؼ­ Àü¿ªÀû(globally)À¸·Î µÉ ¼öµµ ÀÖ½À´Ï´Ù(exec¸¦ ½á¼­).

ls > /dev/null Àº lsÀÇ fs 1 À» /dev/nullÀ¸·Î ¿¬°áÇؼ­ ½ÇÇàÇ϶ó´Â ¶æÀÔ´Ï´Ù.

bash$ lsof -a -p $$ -d0,1,2
COMMAND PID     USER   FD   TYPE DEVICE SIZE NODE NAME
 bash    363 bozo        0u   CHR  136,1         3 /dev/pts/1
 bash    363 bozo        1u   CHR  136,1         3 /dev/pts/1
 bash    363 bozo        2u   CHR  136,1         3 /dev/pts/1


bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID     USER   FD   TYPE DEVICE SIZE NODE NAME
 bash    371 bozo        0u   CHR  136,1         3 /dev/pts/1
 bash    371 bozo        1u   CHR  136,1         3 /dev/pts/1
 bash    371 bozo        2w   CHR    1,3       120 /dev/null


bash$ bash -c 'lsof -a -p $$ -d0,1,2' | cat
COMMAND PID USER   FD   TYPE DEVICE SIZE NODE NAME
 lsof    379 root    0u   CHR  136,1         3 /dev/pts/1
 lsof    379 root    1w  FIFO    0,0      7118 pipe
 lsof    379 root    2u   CHR  136,1         3 /dev/pts/1


bash$ echo "$(bash -c 'lsof -a -p $$ -d0,1,2' 2>&1)"
COMMAND PID USER   FD   TYPE DEVICE SIZE NODE NAME
 lsof    426 root    0u   CHR  136,1         3 /dev/pts/1
 lsof    426 root    1w  FIFO    0,0      7520 pipe
 lsof    426 root    2w  FIFO    0,0      7520 pipe

ÀÌ°ÍÀº ´Ù¸¥ ÇüÅÂÀÇ ÀçÁöÇâ¿¡¼­µµ µ¿ÀÛÇÕ´Ï´Ù.

¿¬½À¹®Á¦: ´ÙÀ½ ½ºÅ©¸³Æ®¸¦ ºÐ¼®ÇØ º¸¼¼¿ä.
#! /usr/bin/env bash                                                                                    
												
mkfifo /tmp/fifo1 /tmp/fifo2                                                                            
while read a; do echo "FIFO1: $a"; done < /tmp/fifo1 &                                                  
exec 7> /tmp/fifo1                                                                                      
exec 8> >(while read a; do echo "FD8: $a, to fd7"; done >&7)                                            
                                                                                                        
exec 3>&1                                                                                               
(                                                                                                       
 (                                                                                                      
  (                                                                                                     
   while read a; do echo "FIFO2: $a"; done < /tmp/fifo2 | tee /dev/stderr | tee /dev/fd/4 | tee /dev/fd/5 | tee /dev/fd/6 >&7 &                                                                        
   exec 3> /tmp/fifo2                                                                                   
                                                                                                        
   echo 1st, to stdout                                                                                  
   sleep 1                                                                                              
   echo 2nd, to stderr >&2                                                                              
   sleep 1                                                                                              
   echo 3rd, to fd 3 >&3                                                                                
   sleep 1                                                                                              
   echo 4th, to fd 4 >&4                                                                                
   sleep 1                                                                                              
   echo 5th, to fd 5 >&5                                                                                
   sleep 1                                                                                              
   echo 6th, through a pipe | sed 's/.*/PIPE: &, to fd 5/' >&5                                          
   sleep 1                                                                                              
   echo 7th, to fd 6 >&6                                                                                
   sleep 1                                                                                              
   echo 8th, to fd 7 >&7                                                                                
   sleep 1                                                                                              
   echo 9th, to fd 8 >&8                                                                                
                                                                                                        
  ) 4>&1 >&3 3>&- | while read a; do echo "FD4: $a"; done 1>&3 5>&- 6>&-                                
 ) 5>&1 >&3 | while read a; do echo "FD5: $a"; done 1>&3 6>&-                                           
) 6>&1 >&3 | while read a; do echo "FD6: $a"; done 3>&-                                                 
                                                                                                        
rm -f /tmp/fifo1 /tmp/fifo2


# °¢ ¸í·É¾î¿Í ¼­ºê½©¿¡ ´ëÇؼ­ ¾î¶² fs °¡ ¹«¾ùÀ» °¡¸£Å°´ÂÁö¸¦ ¾Ë¾Æ³» º¸¼¼¿ä.

exit 0