关于shell内的圆括号的问题,圆括号不是本来就在shell中作与操作吗,为什么还要用转义符转义才能在find中用? 难道说如果不用转义符,其优先级会更高?导致会报错误?姑且先这么记吧。

check: 括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用


检索目录src以及其子孙目录中的所有文件名后缀为.c和.h文件,查找哪些文件中含有字符串TPDU,并列出在这文件中的行号。

答:使用find命令和grep命令。find命令可以在指定的目录树 中查找满足某个条件的文件或目录,并对查找到的满足条件的对象执行一个动作。指定查找条件为“文件名后缀为.c和.h”,动作为“查找哪些文件中含有字符串TPDU,并列出在这文件中的行号”,分别是find的-name和-exec选项。完整的命令为:

1
find src –name "*.[ch]" –exec grep –n TPDU {} /dev/null \;

这里是将grep的数据输出到/dev/null作为垃圾处理吧,但不用>重定向符了?


统计出由用户liu创建并且正在运行的进程数目。

答:使用ps命令列表出系统中所有进程,过滤后仅保留用户liu创建的进程(用grep),每个进程占一行,用wc命令统计一共有多少行即可。 ps –ef | grep liu | wc –l

这里我感觉也可以用ps -ef -u liu | wc -l来替换吧,但是跑出来结果却不同,看来是进程创建者和使用者不同概念,-u只能检索出使用者。


去掉文件list.txt中的所有空行(所谓空行指:行内不含有任何除空格之外的字符),存为新文件list-new.txt。

答:使用grep命令可以用正则表达式对文本文件过滤,-v选项用于筛选掉能匹配指定正则表达式的行,描述一个空行的正则表达式为^ *$,即:从行首开始(^),有零个到多个空格( *),然后是行尾($),命令为: grep –v ’^ *$’ list.txt > list-new.txt

为什么我man grep得到的是--invert-match,显示不匹配的部分呢?,grep实际使用中不需要-v就能识别正则吧。


增量备份 cp -ur test test.bak 不过我实际操作找不到-u,google用的人也不多,都用rsync


LINUX文件权限设计为简单的三级控制,用户liu对用户sun的文件data.txt要么具有全部的读权限,要么不可以读。因此,没有办法限制liu只对文件的指定部分读。

答:错误。可以利用SUID权限,用户sun将文件data.txt的读写权限设置为rw-------,由文件所有者sun自己编写程序以实现对文件的访问,程序中的访问当然可以限制只对文件的指定部分读,但是该程序文件的属性应当为rws--x--x,用户liu只有执行这个可程序程序文件才能实现对文件data.txt的访问。


查看僵尸进程 ps -ef | grep defunct | wc -l


查看进程表表项上限 MacOS下据说写在proc_internal.h中的PID上限是99999,下限是100. 而Linux下32位似乎是32768.

参考资料:http://blog.csdn.net/gatieme/article/details/51058797


Linux操作系统被设计得非常健壮,所以程序在运行过程中不会产生死锁。

答:错误。像信号量等,Linux仅给出了一组信号量操作的机制,如果应用程序设计的多个进程之间对信号量的操作处置不当,仍然可能导致死锁。操作系统没有办法检测出应用进程之间的逻辑操作不正确产生的死锁。使用管道等其他的进程之间通信的系统调用,也可能产生死锁。


Windows用户使用命令行命令ftp从Linux下载文件ftas.c,即使没有病毒破坏,成功下载结束后,下载的文件与原文件也有可能在文件大小(字节数)上不符。

答:正确。这种情况是可能存在的, FTP支持ASCII方式和BINARY方式的文件传输。前者会把数据文件理解为文本文件,会在通信的两个机器之间进行文本文件格式的转换。LINUX和Windows对文本文件的定义方式不同,Windows行间保留“换行”和“回车”两个字符,但是LINUX行间仅包括“换行”一个字符。所以在使用ASCII方式在Windows和Linux间交换文件可能会导致下载的文件与原文件在文件大小(字节数)上不符的情况。


关于文本文件处理的实用程序都有哪些?这些程序都有哪些共同的特点?为什么要这样设计这些命令?

答:关于文本文件处理的实用程序有很多,如:head,tail,sort,grep,wc,cat,od,sed,awk,等等。 这些程序的共同特点是:每个小程序的功能设置简洁;当不指定处理对象时从标准输入获取处理数据;当指定文件名时,从指定的文件中获取处理数据,而且允许指定多于一个的文件名;处理结果在标准输出文件中输出。 这样设计这些命令的原因是:可以利用系统提供的输入、输出重定向和管道,连接和组合多个命令,提供灵活又丰富的使用功能;允许指定多于一个的文件作为处理对象可以和shell 的文件名通配符替换功能配合使用。体现了“策略和机制相分离”的设计理念。系统设计不复杂却可以提供强大的功能。


正则表达式中,一些配对的元字符使用转义时,只需要对开始的一个转义即可。

比如与开方括号 [ 对应的闭方括号 ],与开花括号 { 对应的闭花括号 } ,这两个字符是否元字符,需要依据具体正则表达式的情况确定,我们以闭方括号]的情况为例(}的情况与此类似):如果之前能找到与之对应的元字符开方括号[,则]作为元字符出现,否则,作为普通字符出现。


正则表达式里,使用圆括号时,为什么前面必须要加\转义,变成\(s+\)这样呢?

(4) 将格式为“日-月-年”的日期数据,如:18-06-2010,替换为“年.月.日”格式,如:2010.06.18 s/\([0-9][0-9]*\)-\([0-9][0-9]*\)-\([0-9][0-9]*\)/\3.\2.\1/


正则表达式里,[0-9][0-9]*[0-9]+有什么区别?


记得有一个命令执行以后,整个终端的字符显示会全部错乱,似乎是ASCII序列被打乱了?

好像是执行了一个重定向操作?

并不是,是执行了一个cat命令,打印出一个二进制文件到终端,而这个二进制文件中某个字段可能刚好和某个命令相同,执行出来导致系统字符乱码。


select系统调用的主要作用是什么?

答:使得用户进程可同时等待多个事件发生 用户进程告知内核多个事件,某一个或多个事件发生时select返回,否则,进程睡眠等待。例如:告知内核在rfds集合中的任何文件描述符“读准备好”,或在wfds集合中的任何文件描述符“写准备好”,或在efds集合中的任何文件描述符有“异常情况”发生,或者超时时间tm指定的时间间隔到。


**下列的脚本程序从键盘输入三个整数A,B,C,并且求出A*(B+C)的值。

在划线出填入适当的内容,完成整个程序。显式地标出你所添加的命令中必须有的空格和转义字符,并解释为什么必须这些空格和转义。**

1
2
3
4
5
6
#!/bin/sh
echo –n ”Input A:”; read A
echo –n ”Input B:”; read B
echo –n ”Input C:”; read C
V=
echo ”A*(B+C)=$V”
答:expr $A \* \( $B + $C \) 由于星号和圆括号属于shell的元字符,所以前面增加反斜线,阻止shell对元字符的处理,而是将这些符号直接传递给expr命令。上述命令一共需要6个空格,空格起单词分界线的作用。如果丢失了相应的空格,expr命令将无法得到正确的参数输入,导致expr无法按预期的功能工作。


  1. 写出一段完整的C语言程序,使用fork()系统调用,创建两个子进程,第一个子进程打印HELLO后立刻终止,第二个子进程打印WELCOME后立刻终止,父进程等待两个子进程都终止后,打印BYE然后终止。 答:程序如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    main()
    {
    int sv;
    if (fork() == 0) {
    printf(”HELLO\n”);
    return 0;
    }
    if (fork() == 0) {
    printf(”WELCOME\n”);
    return 0;
    }
    wait(&sv);
    wait(&sv);
    printf(”BYE\n”);
    return 0;
    }
    这里的sv是接收fork的子进程返回的结果,作为子进程的结束。

int execlp(const char * file,const char * arg,……);

execlp的第一个参数是用来在PATH或者路径中查找可执行文件,第二个参数是作为显示的进程名,我设置为aaa,则在ps -ef | grep test中可以查看到这个名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <unistd.h>
#include <stdio.h>


int main(int argc, char *argv[])
{
execlp("ls", "test", "-al",(char*)0); //最后一个0是形同NULL,表示数组的结束
// for(int i = 0;i < 1;i++)
// {
printf("argv[0]:%s\n", argv[0]);
printf("argv[1]:%s\n", argv[1]);
printf("argv[2]:%s\n", argv[2]);
// }
return 0;
}

我这样写执行结果和将第二个参数设置为ls是一样的,只是在查看进程时,名字显示为第二个


管道完整程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>


int main(int argc, char *argv[])
{
int fd[2], sv;
pipe(fd);
//fd[0] = open("out.txt",O_RDONLY);
//fd[1] = open("out.txt", O_WRONLY);
if(fork() == 0)
{
dup2(fd[1],1);
close(fd[1]);
close(fd[0]);
execlp("ls", "test", "-al",(char*)0);
}else if(fork() == 0)
{
dup2(fd[0], 0);
close(fd[1]);
close(fd[0]);
//execlp("ls", "test2", "-l", (char*)0);
execlp("grep", "MtGrep", "javaw", (char*)0);
}
close(fd[1]);
close(fd[0]);
wait(&sv);
wait(&sv);
return 0;
}

linux 执行命令 先搜索Path,而windows先搜索当前目录 区别原因?

考虑到安全问题,如果本地路径下自己写的程序的操作是类似rm -rf /,那就没救了


linux ./操作和. 操作区别

./操作是fork一个子进程执行 . 操作就是用当前的进程直接执行 ---

linux 如何显示出 所有的命令行参数与选项

据说是man argv,不过我执行的是man xargv