HICK 者,乡巴佬也

Linux 环境1(Beginning Linux Programming 笔记8)

Posted in: Linux 编程 — Hick @ 2009/06/07 8:32:56

p170 程åºå‚æ•°

先明确两个概念:选项ã€é€‰é¡¹å‚数。比如 gcc -g -o test test.c ,这里 g å’Œ o 是选项,其中 test 是 o çš„é€‰é¡¹å‚æ•°ï¼Œä¸€èˆ¬ä¹Ÿç›´æŽ¥ç§°ä¸ºå‚数。

c 语言里最常è§çš„ main 函数原型:

int main(int argc, char *argv[])

其中 argc ä¸ºé€‰é¡¹å’Œå‚æ•°çš„个数, argv ä¸ºé€‰é¡¹å’Œå‚æ•°å­—符串数组。

p171 在 main 函数中å¯ä»¥ç›´æŽ¥è¯»å–上é¢çš„两个å˜é‡è޷得傿•°ä¿¡æ¯ï¼š

$ myprog left right ‘and center’

rgc: 4
argv: {“myprogâ€, “leftâ€, “rightâ€, “and centerâ€}

由于一些历å²åŽŸå› ï¼Œlinux/unix ä¸‹çš„å‘½ä»¤çš„é€‰é¡¹å’Œå‚æ•°æ ¼å¼å¹¶æ²¡æœ‰å¾—到很好的统一规和范。比如解压缩命令 tar zxvf httpd-2.0.59.tar.gz ,查看当å‰ç›®å½•文件列表命令 ls -lt 或者 ls -l -t 。一般建议使用横æ åŠ å•个字符或者数字的方å¼ï¼Œæ²¡æœ‰é™„åŠ å‚æ•°çš„选项一般跟上é¢çš„ ls 命令一样,å¯ä»¥åˆå¹¶åˆ°æ¨ªæ ä»¥åŽã€‚有些命令会有相对应的å呿“作命令,比如 set -o xtrace ç”¨æ¥æ‰“å¼€ shell 脚本执行跟踪,而å呿“作为 set +o xtrace æ¥å…³é—­è¯¥åŠŸèƒ½ã€‚

p172 下é¢çš„ç¨‹åºæ¼”示获得一个程åºå‚数的方å¼ï¼š

for(arg = 0; arg < argc; arg++) {
    if(argv[arg][0] == '-')
        printf("option: %s\n", argv[arg]+1);
    else
        printf("argument %d: %s\n", arg, argv[arg]);
}

注æ„上é¢ç¬¬ä¸‰è¡Œ argv[arg]+1 实际上是指针æ“作,输出以åŽå¾—到字符传的一部分。

p173 针对上é¢çš„建议规范,Linux æä¾› getopt æ¥è§£æžé€‰é¡¹å’Œå‚æ•°(注æ„åŒºåˆ†é€‰é¡¹å’Œå‚æ•°)。函数原型:

#include <unistd.h>
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

getopt 扫æ argv ä¸­çš„é€‰é¡¹å’Œå‚æ•°ï¼Œè¿”回 optstring 中定义过的选项å。optstring 中定义的选项ååŽåР冒å·è¡¨ç¤ºè¯¥é€‰é¡¹éœ€è¦å‚数,getopt 在扫æåˆ°è¿™æ ·çš„选项åŽï¼Œä¼šæŠŠå‚数值ä¿å­˜åœ¨å…¨å±€å˜é‡ optarg 中。(###待定) optopt 中ä¿å­˜æœ€åŽä¸€ä¸ªç”± getopt() 返回的已知的选项;扫æåˆ°æœ€åŽä¸€é¡¹ç›®è¿”回 -1 ï¼›é‡åˆ°æ— æ•ˆé€‰é¡¹è¿”回问å·ï¼Œoptopt 包å«äº†æ— æ•ˆé€‰é¡¹å­—符。当 getopt 检测到错误,比如 optstring å®šä¹‰æœ‰å‚æ•°çš„é€‰é¡¹æ²¡æœ‰å‚æ•°æ—¶ï¼Œå¯èƒ½ä¼šæŠ›å‡ºé”™è¯¯ï¼Œé€šè¿‡åœ¨è°ƒç”¨ getopt ä¹‹å‰æŠŠ opterr 设置为 0 或者 optstring 的第一个字符为冒å·å¯ä»¥è®© getopt ä¸æŠ›å‡ºé”™è¯¯ï¼›æŠ‘åˆ¶äº†é”™è¯¯åŽï¼Œéœ€è¦æŒ‡å®šå‚数的选项没有选项时,getopt 在返回该选项的地方返回冒å·ï¼Œæ²¡æœ‰æŠ‘制错误时返回问å·ã€‚实例:

int main(int argc, char * argv[])
{
    int ch;

    while ((ch = getopt(argc, argv, "abcd:")) != -1)
    {
        switch (ch) {
        case 'a':
            printf("option: -a\n");
            break;
        case 'b':
            printf("option: -b\n");
            break;
        case 'c':
            printf("HAVE option: -c\n");
            break;
        case 'd':
            printf("option: -c\n");
            printf("The argument of -b is %s\n", optarg);
            break;
        case '?':
            printf("Unknown option: %c\n",(char)optopt);
            break;
        }
        printf("optind: %d\n", optind);
    }
}

先看下比较正常的执行方å¼:

$ ./a -a -b -c -d hick1 hick2
option: -a
optind: 2
option: -b
optind: 3
HAVE option: -c
optind: 4
option: -c
The argument of -b is hick1
optind: 6

ä¸Šé¢æœ‰ä¸€ä¸ª”䏿­£å¸¸”的地方,就是最åŽä¸€ä¸ªé€‰é¡¹å¤šäº†ä¸€ä¸ªå‚数,getopt å‡½æ•°ä¼šå¿½ç•¥è¿™ä¸ªå‚æ•°ã€‚在扫æåˆ° -a 选项的时候,optind 中ä¿å­˜çš„æ˜¯ä¸‹ä¸€ä¸ªé€‰é¡¹ä¹Ÿå°±æ˜¯ -b 在 agrv 数组中的索引; -d 在 argv 中的索引为 4 ,按照程åºè®¾è®¡åŽé¢éœ€è¦è·Ÿä¸€ä¸ªå‚数,所以 optind 中ä¿å­˜çš„值应该是 6 — å°½ç®¡è¯¥ç´¢å¼•å€¼å¹¶ä¸æ˜¯çœŸæ­£çš„选项。总结æ¥è¯´ï¼Œ optind ä¿å­˜çš„æ˜¯æ ¹æ® optstring 的规则, getopt å³å°†åˆ¤æ–­çš„ä¸‹ä¸€ä¸ªæ˜¯å¦æ˜¯é€‰é¡¹çš„项在 argv 中的索引值。把 -a æ”¾åˆ°æœ€åŽæ‰§è¡Œä¸€ä¸‹å°±å¯ä»¥éªŒè¯ã€‚

å˜é‡ opterr å’Œ optind 都被åˆå§‹åŒ–为1。如果想è¦ç•¥åŽ»å‘½ä»¤è¡Œçš„å‰å‡ ä¸ªå‚数,å¯ä»¥åœ¨è°ƒç”¨ getopt() å‰å°† optind 设æˆå…¶ä»–值。

p175 getopt_long 用æ¥è§£æžå¦å¤–一ç§é£Žæ ¼çš„傿•°ï¼Œæ¯”如 –help 。例å­è™½ç„¶æ˜¯çœ‹æ‡‚了,但是还是有ä¸å°‘疑问,考虑到这å—应用é¢ä¸å¹¿ï¼Œéœ€è¦çš„æ—¶å€™å†è¯¦ç»†æ·±å…¥ã€‚

p177 环境å˜é‡ 我们å¯ä»¥é€šè¿‡ getenv 函数和 putenv ä¸¤ä¸ªå‡½æ•°æ¥æ“作环境å˜é‡ã€‚

#include <stdlib.h>
char *getenv(const char *name);
int putenv(const char *string);

注æ„环境å˜é‡æœ‰è¿™æ ·çš„å­—ç¬¦ä¸²ç»„æˆ name=value 。getenv 会返回 value 的值,找ä¸ç€æ—¶ä¼šè¿”回 null 。如果由于å¯ç”¨å†…å­˜ä¸è¶³å¯¼è‡´ä¿®æ”¹å¤±è´¥(应该很难å‘生å§),会返回 -1 ,这时候全局å˜é‡ errno ä¼šç™¾è®¾ç½®æˆ ENOMEM ã€‚è®¾ç½®å‡½æ•°çš„å‚æ•°å°±æ˜¯ name=value 这样的字符串。

p180 environ å˜é‡ 所有的环境å˜é‡éƒ½ä¿å­˜åœ¨ä¸€ä¸ªå为 environ 的字符串数组中:

#include <stdlib.h>
extern char **environ;

ä¸è¿‡æ²¡æœ‰ç‰¹æ®Šè¦æ±‚,一般建议通过 getenv å’Œ putenv æ¥æ“作环境å˜é‡ï¼Œä¸è¦ç›´æŽ¥æ“作 environ 。下é¢è¿™æ ·å¯ä»¥è¾“出所有的环境å˜é‡ï¼š

#include <stdlib.h>
#include <stdio.h>
extern char **environ;
int main()
{
        char **env = environ;
        while(*env) {
                    printf(“%s\nâ€,*env);
                    env++;
        }
        exit(0);
}

回å¤

Security Image (验è¯ç å¿…须填写)