Linux 环境1(Beginning Linux Programming 笔记8)
p170 程åºå‚æ•°
先明确两个概念:选项ã€é€‰é¡¹å‚数。比如 gcc -g -o test test.c ,这里 g å’Œ o æ˜¯é€‰é¡¹ï¼Œå…¶ä¸ test 是 o çš„é€‰é¡¹å‚æ•°ï¼Œä¸€èˆ¬ä¹Ÿç›´æŽ¥ç§°ä¸ºå‚数。
c è¯è¨€é‡Œæœ€å¸¸è§çš„ main 函数原型:
å…¶ä¸ argc ä¸ºé€‰é¡¹å’Œå‚æ•°çš„个数, argv ä¸ºé€‰é¡¹å’Œå‚æ•°å—符串数组。
p171 在 main 函数ä¸å¯ä»¥ç›´æŽ¥è¯»å–上é¢çš„两个å˜é‡è޷得傿•°ä¿¡æ¯ï¼š
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 下é¢çš„ç¨‹åºæ¼”示获得一个程åºå‚数的方å¼ï¼š
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 æ¥è§£æžé€‰é¡¹å’Œå‚æ•°(注æ„åŒºåˆ†é€‰é¡¹å’Œå‚æ•°)。函数原型:
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 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);
}
}
先看下比较æ£å¸¸çš„æ‰§è¡Œæ–¹å¼:
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 ä¸¤ä¸ªå‡½æ•°æ¥æ“作环境å˜é‡ã€‚
char *getenv(const char *name);
int putenv(const char *string);
注æ„环境å˜é‡æœ‰è¿™æ ·çš„å—ç¬¦ä¸²ç»„æˆ name=value 。getenv 会返回 value 的值,找ä¸ç€æ—¶ä¼šè¿”回 null 。如果由于å¯ç”¨å†…å˜ä¸è¶³å¯¼è‡´ä¿®æ”¹å¤±è´¥(应该很难å‘生å§),会返回 -1 ,这时候全局å˜é‡ errno ä¼šç™¾è®¾ç½®æˆ ENOMEM ã€‚è®¾ç½®å‡½æ•°çš„å‚æ•°å°±æ˜¯ name=value è¿™æ ·çš„å—符串。
p180 environ å˜é‡ 所有的环境å˜é‡éƒ½ä¿å˜åœ¨ä¸€ä¸ªå为 environ çš„å—符串数组ä¸ï¼š
extern char **environ;
ä¸è¿‡æ²¡æœ‰ç‰¹æ®Šè¦æ±‚,一般建议通过 getenv å’Œ putenv æ¥æ“作环境å˜é‡ï¼Œä¸è¦ç›´æŽ¥æ“作 environ 。下é¢è¿™æ ·å¯ä»¥è¾“出所有的环境å˜é‡ï¼š
#include <stdio.h>
extern char **environ;
int main()
{
char **env = environ;
while(*env) {
printf(“%s\nâ€,*env);
env++;
}
exit(0);
}

回å¤