next up previous contents
Next: 錯誤訊息回傳函式 perror Up: main 函式 Previous: 錯誤碼 errno   Contents

STDOUT 與 STDERR

  1. 命令執行時不管正常或錯誤的訊息都輸出到螢幕,但正確的做法應該將正常的輸出送到 STDOUT (標準輸出),錯誤訊息送到 (STDERR),輸出代碼及導向方式如下:
    1. 標準輸出(stdout):代碼為 1 ,使用 >>>
    2. 標準錯誤輸出(stderr):代碼為 2 ,使用 2>2>>
      >, 1>   標準輸出至檔案,該檔案被覆蓋或建立。
      >>, 1>>   標準輸出至檔案,該檔案被建立或累加。
    command 2> 裝置或檔案 錯誤輸出至檔案,該檔案被覆蓋或建立。
      2>>   錯誤輸出至檔案,該檔案被建立或累加。
  2. mainfun3 的 printf 沒有指定輸出,預設輸出到 stdout,所以錯誤訊息直接送到 stdout,將其導向到 /dev/null 時螢幕就沒有任何訊息了,但將 stderr 導向到 /dev/null,螢幕還是印出錯誤訊息,這樣的結果不是正常程式期待的結果。
    [dywang@dyw219 zzz]$ ./mainfun3 /sbin/blkid a
    File renaming error 18: Unknown error
    [dywang@dyw219 zzz]$ ./mainfun3 /sbin/blkid a > /dev/null
    [dywang@dyw219 zzz]$ ./mainfun3 /sbin/blkid a 2> /dev/null
    File renaming error 18: Unknown error
    
  3. 範例:輸出函式 printf 改用 fprintf 並指定輸出到 stderr。
    [dywang@dyw219 zzz]$ vim mainfun4.c
    [dywang@dyw219 zzz]$ cat mainfun4.c
    #include <stdio.h>
    #include <errno.h>
    
    int main( int argc, char *argv[] ) {
    	int result;
    
    	if(argc < 2) {
    		printf("Require TWO arguments\n" );
    		return(1);
    	}
    	result = rename( argv[1], argv[2] );
    	if( result != 0 ) {
    		fprintf(stderr,"File renaming error ");
    		switch(errno) {
    			case EPERM:
    				fprintf(stderr, "%d: Operation not permitted\n", errno);
    				break;
    			case ENOENT:
    				fprintf(stderr, "%d: File not found\n", errno);
    				break;
    			case EACCES:
    				fprintf(stderr, "%d: Permission denied\n", errno);
    				break;
    			default:
    				fprintf(stderr, "%d: Unknown error\n", errno);
    		}
    		return(2);
    	}
    	printf("%d: %s renamed to %s\n", errno, argv[1], argv[2]);
    
    	return(0);
    }
    
  4. 編譯
    [dywang@dyw219 zzz]$ gcc -o mainfun4 mainfun4.c
    
  5. 執行:將 stderr 導向到 /dev/null,螢幕沒有輸出任何訊息,可以確認錯誤碼 18 的錯誤訊息是送到 stderr。
    [dywang@dyw219 zzz]$ ./mainfun4 /sbin/blkid a > /dev/null
    File renaming error 18: Unknown error
    [dywang@dyw219 zzz]$ ./mainfun4 /sbin/blkid a 2> /dev/null
    



De-Yu Wang 2019-09-19