webdancer's Blog

linux 必学命令( 转)

 Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作、文件存取、目录操作、进程管理、文件权限设定等。所以,在Linux系统上工作离不开使用系统提供的命令。要想真正理解Linux系统,就必须从Linux命令学起,通过基础的命令学习可以进一步理解Linux系统。

不同Linux发行版的命令数量不一样,但Linux发行版本最少的命令也有200多个。这里笔者把比较重要和使用频率最多的命令,按照它们在系统中的作用分成下面六个部分一一介绍。

◆ 安装和登录命令:login、shutdown、halt、reboot、install、mount、umount、chsh、exit、last;
◆ 文件处理命令:file、mkdir、grep、dd、find、mv、ls、diff、cat、ln;
◆ 系统管理相关命令:df、top、free、quota、at、lp、adduser、groupadd、kill、crontab
◆ 网络操作命令:ifconfig、ip、ping、netstat、telnet、ftp、route、rlogin、rcp、finger、mail、 nslookup;
◆ 系统安全相关命令:passwd、su、umask、chgrp、chmod、chown、chattr、sudo ps、who;
◆ 其它命令:tar、unzip、gunzip、unarj、mtools、man、unendcode、uudecode。

os实验1 ——进程控制

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>
#include<stdlib.h>
typedef  void (*sighandler_t) (int);
void sincon()
{
}
int main()
{
    pid_t p0;
    int sta0,sta1;
    signal(SIGINT,(sighandler_t)sincon);
    while(1)
    {
        if((p0=fork())<0)
        {
            perror("error!fork first child");
            exit(0);
        }
        else if(p0==0)
        {
            pause();
            sta0=execlp("/bin/ls","ls",NULL);
            exit(0);
        }
        else
        {
            pid_t p1;
            if((p1=fork())<0)
            {
                perror("error!fork second child");
                exit(0);
            }
            else if(p1==0)
            {
                printf("exe the second child\n");
                sta1=execlp("/bin/ps","ps",NULL);
                exit(0);
            }
            else
            {
                if(waitpid(p1,&sta1,0)!=p1)
                    perror("error!");
                if((kill(p0,SIGINT))>=0)
                    printf("wake up first child\n");
                sleep(3);
            }
        }
    }
    return 0;
}

 

 

fork函数二三事

1.fork函数的基本功能

在linux中,只有一个函数可以创建子进程:fork。

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);

由fork创建的新进程被称为子进程( child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程I D。将子进程I D返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程I D。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID(进程ID 0总是由交换进程使用,所以一个子进程的进程ID不可能为0 )。

2.CoW(Copy on Write)

CoW是现代操作系统中的一个很重要的策略,在fork中也使用了。看一下下面这个例子。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
int main(){
          int i;
          pid_t p0;
          if((p0=fork())<0){
                 perror("error!");
                 exit(0);
}
         else if(p0==0){
                 i=getpid();
                 printf("i is %d the i address is %p in the child\n",i,&i);
         }
         else {
                 i=getpid();
                 printf("i is %d the i address is %p in the parent\n",i,&i);
         }
         return 0;
 }

 运行的结果:

i is 3132 the i address is 0xbf8147e8 in the parent
i is 3133 the i address is 0xbf8147e8 in the child

为什么会有相同的i地址呢?不是当fork()产生子进程的时候,会copy吗?
因为现代的OS基本采用了COW技术。父子进程共享数据和堆。

3.缓冲问题

在这里http://coolshell.cn/articles/7965.html看到了一个很有趣的问题,代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main(void)
{
   int i;
   for(i=0; i<2; i++){
      fork();
      printf("-");
   }
 
   return 0;
}

问一下:上面到底会输出几个‘-'。答案不是六个,而是八个。原因就是因为父进程的buffer也被子进程继承了。详细的分析可以参照Coolshell的这篇文章http://coolshell.cn/articles/7965.html。

 

 

 

clone 创建对象副本

public interface Cloneable

 此类实现了 Cloneable 接口,以指示方法Object.clone()可以合法地对该类实例进行按字段复制。

如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。

按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的)。请参阅 Object.clone(), 以获得有关重写此方法的详细信息。

但是如果直接查询JDK文档会发现Cloneable接口中并没有任何的方法定义,所以此接口在设计上称为是一种标识接口,表示对象可以被克隆。

 

  1. class Person implements Cloneable { // 
    必须实现Cloneable接口
     
  2.     private String name = null;  
  3.     public Person(String name) {  
  4.         this.name = name;  
  5.     }  
  6.     public void setName(String name) {  
  7.         this.name = name;  
  8.     }  
  9.     public String getName() {  
  10.         return this.name;  
  11.     }  
  12.     // 需要子类覆写clone方法  
  13.     public Object clone() throws 
    CloneNotSupportedException {  
  14.         return super.clone();       //
    具体的克隆操作由父类完成
     
  15.     }  
  16.     public String toString() {  
  17.         return "姓名:" + this.getName();  
  18.     }  
  19. };  
  20. public class CloneDemo01 {  
  21.     public static void main(String[] args) 
    throws Exception {  
  22.         Person p1 = new Person("张三");  
  23.         Person p2 = (Person) p1.clone();  
  24.         p2.setName("李四");  
  25.         System.out.println("原始对象:" + p1);  
  26.         System.out.println("克隆之后的对象:" + p2);  
  27.     }  
  28. }

Math类及类型转换

1)Math类,位于java.lang包里。里面封装了数学常量及常用的函数。

2)类型转化:1)低精度向高精度转。

 

                 2)强制类型转换。使用()。

注意:通常,不将布尔类型与其它类型转化,防止一些错误。

3)大数值问题。

BigInteger表示是大整数类,定义在java.math包中,如果在操作时一个整型数据已经超过了整数的最大类型长度long,数据无法装入,此 时可以使用.

同时,提供了基本的算术运算。+ -  *  / 等。(有时很有用的吆!)

 

 

 

java基本输入输出

输入:

利用scanner类,jdk5.0以后新增类。

1)Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。它附属于标准输入流System.in。

2)基本用法:

 

Scanner sc=new Scanner(System.in);
int i=sc.nextInt();

3)包:Java.util.*

输出:

1)System.out类封装了很多输出方法。print,println,当然还有我们c里面的printf。(jdk1.5沿用了c)

2)printf的格式方法:

整数: d(10) , x(16), o(8)

浮点数:f (定点),e(指数)  ,g(通用) ,a (16浮点)

字符:c

字符串:s

布尔: b

时间:t

(详细:printf)。

真悲哀,当时学的时候只用了print ,println!

 

 

 

 

 

 




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee