QuietHeart's Site

Linux杂乱记录


目录

本文主要记录使用linux过程中记录的杂乱问题,适时可能会整理至特定的地方.

1 介绍

文章可以以二级标题开始,便于将来父级追加,这一点不知道是否必要.

1.1 子标题1

子标题内容

  1. 列表项目1。
  2. 列表项目2。

1.2 子标题2:

子标题2的内容

2 内容1

规整好的内容1

3 内容2

规整好的内容2

4 Miscellaneous

介绍没有明确规整,或有待规整的内容.

4.1 —— [2015-10-28 三 11:32] Cscope 没有文件的错误------

From:/home/miracle/mydata/orgmode/gtd/next.org

参考:http://www.21qa.net/questions/2699/2699 Error detected while processing ~/.vimrc: cs_read_prompt EOF: No such file or directory E609: Cscope error: cscope: cannot read trailer offset from file cscope.outc

使用cscope查看程序代码遇到一个问题,就是在配置vim中默认打开cscope.out文件出现如上错误,经google后发现的问题是代码所放的文件夹命名中存在了“空格 ”,解决办法就是将文件夹重命名,用‘-’或英文等符号替代空格。

4.2 —— [2016-01-31 日 11:12] top再H即可list by thread------

From:/home/miracle/mydata/orgmode/gtd/_next.org

4.3 —— [2016-01-31 日 14:42] Linux进程状态机与ps关联------

From:/home/miracle/mydata/orgmode/gtd/_next.org

参考:http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html

进程是通过fork系列的系统调用(fork、clone、vfork)来创建的,内核(或内核模块)也可以通过kernel_thread函数创建内核进程。这些创建子进程的函数本质上都完成了相同的功能——将调用进程复制一份,得到子进程。(可以通过选项参数来决定各种资源是共享、还是私有。) 那么既然调用进程处于TASK_RUNNING状态(否则,它若不是正在运行,又怎么进行调用?),则子进程默认也处于TASK_RUNNING状态。 另外,在系统调用clone和内核函数kernel_thread也接受CLONE_STOPPED选项,从而将子进程的初始状态置为 TASK_STOPPED。

  进程创建后,状态可能发生一系列的变化,直到进程退出。而尽管进程状态有好几种,但是进程状态的变迁却只有两个方向——从TASK_RUNNING状态变为非TASK_RUNNING状态、或者从非TASK_RUNNING状态变为TASK_RUNNING状态。总之,TASK_RUNNING是必经之路,不可能两个非RUN状态直接转换。

也就是说,如果给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNING状态),然后再响应SIGKILL信号而退出(变为TASK_DEAD状态)。并不会从TASK_INTERRUPTIBLE状态直接退出。

  进程从非TASK_RUNNING状态变为TASK_RUNNING状态,是由别的进程(也可能是中断处理程序)执行唤醒操作来实现的。执行唤醒的进程设置被唤醒进程的状态为TASK_RUNNING,然后将其task_struct结构加入到某个CPU的可执行队列中。于是被唤醒的进程将有机会被调度执行。

  而进程从TASK_RUNNING状态变为非TASK_RUNNING状态,则有两种途径:

  1、响应信号而进入TASK_STOPED状态、或TASK_DEAD状态;   2、执行系统调用主动进入TASK_INTERRUPTIBLE状态(如nanosleep系统调用)、或TASK_DEAD状态(如exit系统调用);或由于执行系统调用需要的资源得不到满     足,而进入TASK_INTERRUPTIBLE状态或TASK_UNINTERRUPTIBLE状态(如select系统调用)。   显然,这两种情况都只能发生在进程正在CPU上执行的情况下。

通过ps命令我们能够查看到系统中存在的进程,以及它们的状态:

R(TASK_RUNNING),可执行状态。

只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。进程调度器的任务就是从各个CPU的可执行队列中分别选择一个进程在该CPU上运行。 只要可执行队列不为空,其对应的CPU就不能偷懒,就要执行其中某个进程。一般称此时的CPU“忙碌”。对应的,CPU“空闲”就是指其对应的可执行队列为空,以致于CPU无事可做。 有人问,为什么死循环程序会导致CPU占用高呢?因为死循环程序基本上总是处于TASK_RUNNING状态(进程处于可执行队列中)。除非一些非常极端情况(比如系统内存严重紧缺,导致进程的某些需要使用的页面被换出,并且在页面需要换入时又无法分配到内存……),否则这个进程不会睡眠。所以CPU的可执行队列总是不为空(至少有这么个进程存在),CPU也就不会“空闲”。

很多操作系统教科书将正在CPU上执行的进程定义为RUNNING状态、而将可执行但是尚未被调度执行的进程定义为READY状态,这两种状态在linux下统一为 TASK_RUNNING状态。

S(TASK_INTERRUPTIBLE),可中断的睡眠状态。

处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对应的等待队列中的一个或多个进程将被唤醒。

通过ps命令我们会看到,一般情况下,进程列表中的绝大多数进程都处于TASK_INTERRUPTIBLE状态(除非机器的负载很高)。毕竟CPU就这么一两个,进程动辄几十上百个,如果不是绝大多数进程都在睡眠,CPU又怎么响应得过来。

D(TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。

与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。 绝大多数情况下,进程处在睡眠状态时,总是应该能够响应异步信号的。否则你将惊奇的发现,kill -9竟然杀不死一个正在睡眠的进程了!于是我们也很好理解,为什么ps命令看到的进程几乎不会出现TASK_UNINTERRUPTIBLE状态,而总是TASK_INTERRUPTIBLE状态。

而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程(这个插入的流程可能只存在于内核态,也可能延伸到用户态),于是原有的流程就被中断了(参见《linux异步信号handle浅析》)。 在进程对某些硬件进行操作时(比如进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互),可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。(比如read系统调用触发了一次磁盘到用户空间的内存的DMA,如果DMA进行过程中,进程由于响应信号而退出了,那么DMA正在访问的内存可能就要被释放了。)这种情况下的TASK_UNINTERRUPTIBLE状态总是非常短暂的,通过ps命令基本上不可能捕捉到。

linux系统中也存在容易捕捉的TASK_UNINTERRUPTIBLE状态。执行vfork系统调用后,父进程将进入TASK_UNINTERRUPTIBLE状态,直到子进程调用exit或exec。 通过下面的代码就能得到处于TASK_UNINTERRUPTIBLE状态的进程: #include <unistd.h> void main() { if (!vfork()) sleep(100); } 编译运行,然后ps一下: kouu@kouu-one:~/test$ ps -ax | grep a\.out 4371 pts/0 D+ 0:00 ./a.out 4372 pts/0 S+ 0:00 ./a.out 4374 pts/1 S+ 0:00 grep a.out 然后我们可以试验一下TASK_UNINTERRUPTIBLE状态的威力。不管kill还是kill -9,这个TASK_UNINTERRUPTIBLE状态的父进程依然屹立不倒。

T(TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。

向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态(除非该进程本身处于TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL信号一样,是非常强制的。不允许用户进程通过signal系列的系统调用重新设置对应的信号处理函数。) 向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。

当进程正在被跟踪时,它处于TASK_TRACED这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。比如在gdb中对被跟踪的进程下一个断点,进程在断点处停下来的时候就处于TASK_TRACED状态。而在其他时候,被跟踪的进程还是处于前面提到的那些状态。 对于进程本身来说,TASK_STOPPED和TASK_TRACED状态很类似,都是表示进程暂停下来。 而TASK_TRACED状态相当于在TASK_STOPPED之上多了一层保护,处于TASK_TRACED状态的进程不能响应SIGCONT信号而被唤醒。只能等到调试进程通过ptrace系统调用执行PTRACE_CONT、PTRACE_DETACH等操作(通过ptrace系统调用的参数指定操作),或调试进程退出,被调试的进程才能恢复TASK_RUNNING状态。

Z(TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。

进程在退出的过程中,处于TASK_DEAD状态。

在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。 之所以保留task_struct,是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。比如在shell中,$?变量就保存了最后一个退出的前台进程的退出码,而这个退出码往往被作为if语句的判断条件。 当然,内核也可以将这些信息保存在别的地方,而将task_struct结构释放掉,以节省一些空间。但是使用task_struct结构更为方便,因为在内核中已经建立了从pid到task_struct查找关系,还有进程间的父子关系。释放掉task_struct,则需要建立一些新的数据结构,以便让父进程找到它的子进程的退出信息。

父进程可以通过wait系列的系统调用(如wait4、waitid)来等待某个或某些子进程的退出,并获取它的退出信息。然后wait系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉。 子进程在退出的过程中,内核会给其父进程发送一个信号,通知父进程来“收尸”。这个信号默认是SIGCHLD,但是在通过clone系统调用创建子进程时,可以设置这个信号。

通过下面的代码能够制造一个EXIT_ZOMBIE状态的进程: #include <unistd.h> void main() { if (fork()) while(1) sleep(100); } 编译运行,然后ps一下: kouu@kouu-one:~/test$ ps -ax | grep a\.out 10410 pts/0 S+ 0:00 ./a.out 10411 pts/0 Z+ 0:00 [a.out] <defunct> 10413 pts/1 S+ 0:00 grep a.out

只要父进程不退出,这个僵尸状态的子进程就一直存在。那么如果父进程退出了呢,谁又来给子进程“收尸”? 当进程退出的时候,会将它的所有子进程都托管给别的进程(使之成为别的进程的子进程)。托管给谁呢?可能是退出进程所在进程组的下一个进程(如果存在的话),或者是1号进程。所以每个进程、每时每刻都有父进程存在。除非它是1号进程。

1号进程,pid为1的进程,又称init进程。 linux系统启动后,第一个被创建的用户态进程就是init进程。它有两项使命: 1、执行系统初始化脚本,创建一系列的进程(它们都是init进程的子孙); 2、在一个死循环中等待其子进程的退出事件,并调用waitid系统调用来完成“收尸”工作; init进程不会被暂停、也不会被杀死(这是由内核来保证的)。它在等待子进程退出的过程中处于TASK_INTERRUPTIBLE状态,“收尸”过程中则处于TASK_RUNNING状态。

X(TASK_DEAD - EXIT_DEAD),退出状态,进程即将被销毁。

而进程在退出过程中也可能不会保留它的task_struct。比如这个进程是多线程程序中被detach过的进程(进程?线程?参见《linux线程浅析》)。或者父进程通过设置SIGCHLD信号的handler为SIG_IGN,显式的忽略了SIGCHLD信号。(这是posix的规定,尽管子进程的退出信号可以被设置为SIGCHLD以外的其他信号。) 此时,进程将被置于EXIT_DEAD退出状态,这意味着接下来的代码立即就会将该进程彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。

4.4 DONE ubuntu无线热点供android使用

  • State "DONE" from "WAIT/FORWARD" [2016-04-16 六 16:47]
  • State "WAIT/FORWARD" from "INBOX" [2016-03-15 二 12:15]
    等待整理

Capture Time:[2016-03-15 二 11:33]


使用Ubuntu自带的wifi热点设置,一般android无法联网,因为一般android不支持ad-hoc模式。 可借助如下方式实现ubuntu共享wifi热点。

系统:Ubuntu 12.04

4.4.1 安装所需工具

$sudo apt-get install hostapd dnsmasq

4.4.2 修改配置文件

修改配置: /etc/hostapd.conf, /etc/dnsmasq.conf, /etc/sysctl.conf

/etc/hostapd.conf 编辑如下:

interface=wlan0
driver=nl80211
ssid=CMCC_QUIET
hw_mode=g
channel=11
dtim_period=1
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=3
ieee80211n=0
wpa=3
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

/etc/dnsmasq.conf 加入如下:

interface=wlan0

#这个是只监听wlan0,没有之会检测所有卡
bind-interfaces
except-interface=lo

#设置dhcp地址范围,即租借时间6小时
dhcp-range=192.168.1.100,192.168.1.254,12h
#address=/#/10.0.0.1#如果你的配置中有这个,请注释掉,应为这个会把#(代表所有网址)的dns到10.1.1.1这个地址

#为手机配置网关,要和dhcp-arange对应,这涉及网络的知识,不详细介绍。
dhcp-option=3,192.168.1.1

#为手机配置dns,你可以根据实际情况去修改
dhcp-option=6,202.114.128.2

/etc/sysctl.conf 修改如下: 为了确保打开了转发的功能,还要修改文件 /etc/sysctl.conf 。打开文件 /etc/sysctl.conf ,找到 net.ipv4.ip_forward=1 ,如果被注释了,要将其前面的注释去掉,以便使其生效。

4.4.3 运行相关内容

首先创建 myap.sh 脚本用于端口转发。 myap.sh 内容如下:

#!/bin/sh
#为无线添加路由规则
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t nat -APOSTROUTING -s 192.168.1.0/24 -o eth0 -jMASQUERADE
iptables -A FORWARD -s 192.168.1.0/24 -o eth0 -jACCEPT
iptables -A FORWARD -d 192.168.1.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -i eth0 -jACCEPT

依次运行如下命令:

$sudo killall named  #一般情况下bind的named会占了53端口,从而导致dnsmasq启动不了,所以要用killallnamed来杀了named再启动dnsmasq。
$sudo killall hostapd
$sudo ifconfig wlan0 192.168.1.1 #由于上面我们将dhcp-range设置为192.168.1.100,192.168.1.254,所以这里我们要将wlan0的ip设置为同一网段的ip。
$sudo hostapd -B /etc/hostapd.conf
$sudo /etc/init.d/dnsmasq restart #使用静态ip的朋友注意了,dnsmasq启动后会出现电脑突然上不了网,因为dnsmasq更了/etc/resolv.conf的原因。可以在/etc/resolv.conf加一行,执行命令echo"nameserver202.114.128.2">>/etc/resolv.conf即可。202.114.128.2是dns服务器,你可以根据你的当地的实际情况去修改。
#echo 1 >/proc/sys/net/ipv4/ip_forward #启动转发功能。
$sudo ./myap#如果你的myap不在当前路径下,要加路径/
4.4.3.1 总结

给出一个脚本, mywifi.sh, 运行之时只需要: sudo ./mywifi.sh start 即可。

#!/bin/sh

#you must install hostapd, and dnsmasq

do_start()
{
        ifconfig wlan0 10.1.1.1 netmask 255.255.255.0
        ifconfig wlan0 up
        killall named
        killall hostapd
        ifconfig wlan0 10.1.1.1
        hostapd -B /etc/hostapd.conf
        /etc/init.d/dnsmasq restart

        echo 1 >/proc/sys/net/ipv4/ip_forward
        #sysctl  -w net.ipv4.ip_forward=1
        iptables -F
        iptables -X
        iptables -t nat -F
        iptables -t nat -X
        iptables -t nat -APOSTROUTING -s 10.1.1.0/24 -o eth0 -jMASQUERADE
        iptables -A FORWARD -s 10.1.1.0/24 -o eth0 -jACCEPT
        iptables -A FORWARD -d 10.1.1.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -i eth0 -jACCEPT
}

do_stop()
{
        iptables -X
        iptables -F
        echo 0 >/proc/sys/net/ipv4/ip_forward
        #/etc/init.d/dnsmasq stop
        #killall named
        killall hostapd
        ifconfig wlan0 down
}

show_help()
{
        echo "usage: $0 [start |stop]"
}

case $1 in
"start")
        do_start $*
        ;;
"stop")
        do_stop $*
        ;;
*)
        show_help
        ;;
esac
__tmp_return=$?
exit $__tmp_return

4.4.5 WAIT/FORWARD Ubuntu wifi(hostapd+udhcpd)

  • State "WAIT/FORWARD" from "INBOX" [2016-08-16 二 16:37]
    wait for arranged.

Capture Time:[2016-08-16 二 16:01]


  1. hostapd

    $sudo apt-get install hostapd
    
  2. udhcpd

    $sudo apt-get install udhcpd
    
  3. hostapd config

    $vim hostapd.conf
    interface=wlan0
    driver=nl80211
    ssid=<your ssid name>
    hw_mode=g
    channel=11
    dtim_period=1
    rts_threshold=2347
    fragm_threshold=2346
    macaddr_acl=0
    auth_algs=3
    ieee80211n=0
    wpa=3
    wpa_passphrase=<your password>
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP
    
  4. udhcpd config

    $vim /etc/udhcpd.conf
    ...
    start                10.1.1.100      #default: 192.168.0.20
    end          10.1.1.200      #default: 192.168.0.254
    ...
    # The interface that udhcpd will use
    interface    wlan0           #default: eth0
    ...
    opt  dns     10.1.1.1 114.114.114.114
    option       subnet  255.255.255.0
    opt  router  10.1.1.1
    opt  wins    10.1.1.1
    option       dns     129.219.13.81   # appened to above DNS servers for a total of 3
    option       domain  local
    option       lease   864000          # 10 days of seconds
    ...
    
    $vim /etc/default/udhcpd
    ...
    #DHCPD_ENABLED="no"
    ...
    
  5. start/stop

    $vim mywifi.sh
    #!/bin/sh
    
    #you must install hostapd, and dnsmasq
    
    do_start()
    {
         ifconfig wlan0 10.1.1.1 netmask 255.255.255.0
         ifconfig wlan0 up
         killall named
         killall hostapd
         ifconfig wlan0 10.1.1.1
         hostapd -B /etc/hostapd.conf
         /etc/init.d/udhcpd start
    
         echo 1 >/proc/sys/net/ipv4/ip_forward
         #sysctl  -w net.ipv4.ip_forward=1
         iptables -F
         iptables -X
         iptables -t nat -F
         iptables -t nat -X
         iptables -t nat -APOSTROUTING -s 10.1.1.0/24 -o eth0 -jMASQUERADE
         iptables -A FORWARD -s 10.1.1.0/24 -o eth0 -jACCEPT
         iptables -A FORWARD -d 10.1.1.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -i eth0 -jACCEPT
    }
    
    do_stop()
    {
         #iptables -D FORWARD -d 10.1.1.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -i eth0 -jACCEPT
         #iptables -D FORWARD -s 10.1.1.0/24 -o eth0 -jACCEPT
         iptables -t nat -DPOSTROUTING -s 10.1.1.0/24 -o eth0 -jMASQUERADE
         iptables -X
         iptables -F
         echo 0 >/proc/sys/net/ipv4/ip_forward
         /etc/init.d/udhcpd stop
         #killall named
         killall hostapd
         ifconfig wlan0 down
    }
    
    show_help()
    {
         echo "usage: $0 [start |stop]"
    }
    
    case $1 in
    "start")
         do_start $*
         ;;
    "stop")
         do_stop $*
         ;;
    * )
         show_help
         ;;
    
    esac
    __tmp_return=$?
    exit $__tmp_return
    

    有时候无法联网,可以尝试一下如下:

    $sudo ip route del 10.1.1.0/24
    $sudo ip route add 10.1.1.0/24 via 10.1.1.1 dev wlan0 src 10.1.1.1
    

4.5 DONE 结合coredump调试

  • State "DONE" from [2016-08-24 三 10:52]

关于coredump, 具体可参见 http://vaqeteart.iteye.com/blog/1013397

大致注意如下:

  1. coredump 是程序崩溃前系统为其生成的内存快照.
  2. coredump 默认存放在当前进程工作路径,也有些系统会生成到特定的目录中,需要自己确认.
  3. 需要打开系统coredump开关,才可令系统在程序崩溃前生成coredump.

    # ulimit -c unlimited
    
  4. coredump的读取
    • 确认coredump类型用file,例如

      $file core.pid 
      core.pid: ELF 32-bit LSB core file ARM, version 1 (SYSV), SVR4-style, from 'nt_'
      
    • 查看基本信息用 readelf 或者 objump 结合相应选项,例如:

      $ readelf -h core.pid 
      ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              CORE (Core file)
      Machine:                           ARM
      Version:                           0x1
      ...
      
      $objdump -x -C core.pid
      
      core.pid:     file format elf32-little
      core.pid
      architecture: UNKNOWN!, flags 0x00000000:
      
      start address 0x00000000
      
      Program Header:
       NOTE off    0x000012d4 vaddr 0x00000000 paddr 0x00000000 align 2**0
            filesz 0x0000198c memsz 0x00000000 flags ---
       LOAD off    0x00003000 vaddr 0x7f555000 paddr 0x00000000 align 2**12
            filesz 0x00000000 memsz 0x00005000 flags r-x
       LOAD off    0x00003000 vaddr 0x7f55a000 paddr 0x00000000 align 2**12
            filesz 0x00001000 memsz 0x00001000 flags r--
       LOAD off    0x00004000 vaddr 0x7f55b000 paddr 0x00000000 align 2**12
            filesz 0x00001000 memsz 0x00001000 flags rw-
      ...
      Sections:
      Idx Name          Size      VMA       LMA       File off  Algn
      0 note0         0000198c  00000000  00000000  000012d4  2**0
                       CONTENTS, READONLY
      1 .auxv         00000090  00000000  00000000  000014b8  2**2
                       CONTENTS
      2 .reg2/0       00000074  00000000  00000000  000023fc  2**2
      ...
      SYMBOL TABLE:
      no symbols
      
  5. gdb结合coredump调试,有助于迅速找到程序发生崩溃的位置.

    $gdb a.out core.pid
    

4.5.1 杂乱

4.5.1.1 在特定的位置生成coredump
5596L TV coredump 的命令如下:
1. cd /tmp
2. chmod –R 777 mnt
3. ulimit -c unlimited
4. echo 1 > /proc/sys/kernel/core_uses_pid
5. echo /mnt/usb/sda1/core_%e_sig%s_pid%p > /proc/sys/kernel/core_pattern

这样可以抓到browser.out crash时的coredump.

4.6 WAIT/FORWARD 添加超级用户权限 sudo adduser xxx sudo

  • State "WAIT/FORWARD" from [2016-10-24 一 10:51]
    wait for more organize.

或者直接修改 /etc/sudoers 文件

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification 对单个用户的权限设置
root	ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges 对admin组的权限设置
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command 对sudo组的权限设置
%sudo	ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

所以前面的 adduser xxx sudo 会将 xxx 添加到sudo组中,具有了相应的权限(需要重新login)。

4.7 WAIT/FORWARD ssh配置文件简化登录过程

  • State "WAIT/FORWARD" from "INBOX" [2016-08-08 一 12:03]
    wait for more

Capture Time:[2016-08-08 一 11:56]


  • 生成密钥对儿

    $ssh-keygen
    

    会自动生成公钥密钥对,生成位置是 ~/.ssh

  • 免密

    $ssh-copy-id <ip>
    

    将本地公钥拷贝到远端服务器,使之被远端被登录主机信任本地机,从而实现免密登录。即登录的时候不用输入密码。

    需要远端主机对ssh服务端也进行相应的配置,使之激活免密。

  • 免输入用户名密码

    在客户端为被主机配置好别名和端口:

    $vim ~/.ssh/config
    #Myname1
    Host myname1
    HostName <host ip>
    User <username>
    Port <ssh port, default 22>
    IdentityFile ~/.ssh/id_rsa
    

    登录:

    $ssh myname1
    

另外,设置免密之后,scp命令也支持tab远程补全了,拷贝远程文件很方便。

4.8 >>>>> [2017-03-22 三 09:28] 查看一个进程的环境变量

From:/home/miracle/mydata/orgmode/gtd/output/prosody_src_study.org

进程运行的环境变量在:

$cat /proc/pid/environ

默认没有换行的话可以:

$cat /proc/pid/environ |tr -s '\x0' '\n'

效果类似

$cat /proc/pid/environ |sed -e 's/\x0/\n/g'

最简单的方法:

$strings /proc/pid/environ

注意,这个环境变量的值是静态的。如果进程在运行期间用setenv等修改了环境变量,虽然进程实际环境变量变化了,但是这个文件的内容是不变的。 可以这样检测:

  1. tty 确认当前bash 终端
  2. ps 查看当前bash的pid,假设为 bashpid
  3. cd /proc/<bashpid>
  4. 查看 string environ
  5. 设置一个bash环境变量TEST=test
  6. 再次查看 string =environ

4.9 Linux系统管理杂技

4.9.1 Linux如何查看当前占用CPU或内存最多的几个进程

4.9.1.1 ps
$ps -aux | sort -k4nr | head -N

ps aux 输出类似:

$ ps aux |head -n 10
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  40448  3076 ?        Ss   Jun19   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Jun19   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Jun19   0:09 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   Jun19   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    Jun19   0:00 [migration/0]
root         8  0.0  0.0      0     0 ?        S    Jun19   0:00 [rcu_bh]
root         9  0.0  0.0      0     0 ?        S    Jun19   0:00 [rcuob/0]
root        10  0.0  0.0      0     0 ?        S    Jun19   0:00 [rcuob/1]
root        11  0.0  0.0      0     0 ?        S    Jun19   0:00 [rcuob/2]
...

参数 a 指代all——所有的进程, u 指代userid——执行该进程的用户id, x 指代显示所有程序,不以终端机来区分。

sort -k4nr 中( k 代表从根据哪一个关键词排序,后面的数字4表示按照第四列排序; n 指代numberic sort,根据其数值排序; r 指代reverse,这里是指反向比较结果,输出时默认从小到大,反向后从大到小。)。本例中,可以看到%MEM在第4个位置,根据%MEM的数值进行由大到小的排序。 -k3 表示按照cpu占用率排序。

4.9.1.2 top

命令行输入 top 回车,然后按下大写 M 按照memory排序,按下大写 P 按照CPU排序。

参考:http://blog.csdn.net/u013181648/article/details/68941971

4.9.2 踢出特定终端的用户

结合 who 命令, 使用 pkill -KILL -t tty1, 需要超级用户权限。

4.9.3 限制占用资源过多的进程

发现CPU占用率超过某个限制的用户进程,然后将该进程杀死,这种做法很暴力,而且用户发现他的进程被杀以后很可能又启动进程,这样恶性循环。 有一种折中的方法,不是将目标进程杀死,而是适当调整其nice值。 例如:

$renice +10 `ps aux | awk '{ if ($3 > 0.8 && id -u $1 > 500) print $2}'`

可结合 ps aux 输出分析该命令: 可知这里 $1 是用户名,将 >500 修改,可以直接限制某用户。比如:

$renice +10 `ps aux | awk '{ if ($3 > 0.8 && id -u $1 == id -u xxx) print $2}'`

其实实践发现:

#renice -n 10 -u miracle

会将 miracle 的nice值增加10

4.9.4 局域网间文件互传

4.9.4.1 通过nc

client on windows(cygwin):

$nc -l 55555 | tar xzvf -

server:

$tar czvf - <your dir/file> | nc 172.16.246.210 55555
4.9.4.2 其它

通过scp/winscp/rsync/rcp/smb/ftp/sftp/ssh/tftp

4.10 意外发现

gnome-terminal 应用中,切换各个 tab 除了可以用 Alt-1, Alt-2, ... 之外,还可以用 C-PgUp, C-PgDn.

4.11 REFERENCE 一个便于调试的源码编译软件安装技巧

4.11.1 问题

假设源代码编译安装的路径prefix为 /usr/local/develop,

如果所有软件安装都用这个目录,那么如果某个软件安装中出现失误,很难回滚包含了很多之前软件安装的 /usr/loca/develop 目录。

4.11.2 整体思想

  • 安装每一个安装包的时候,先将原来的 /usr/local/develop 备份,
  • 然后将新的软件安装到空的 /usr/local/develop , 安装之后,重命名为 /usr/local/develop.xxx,
  • 然后恢复原来那个备份的 /usr/local/develop ,再将新备份的 /usr/local/develop.xxxcp -af xxxln -s xxx 的方式合并到原来的 /usr/local/develop .

当软件安装出现问题的时候(即 /usr/local/develop 目录会混乱掉),这个时候只需要简单删除掉合并的 /usr/local/develop, 重新建立总合并的目录,然后把没有问题的软件合并到干净的 /usr/local/develop 中去。

4.11.3 执行过程

如下,最开始路径:

$sudo mkdir -p /usr/local/backup_installs
$sudo mkdir -p /usr/local/backup_installs/develop.all #所有的软件安装最终实际合并到这里
$sudo ln -s /usr/local/backup_installs/develop.all /usr/local/develop #对外表现为一个路径:/usr/local/develop

安装xxx软件的时候

$sudo mv /usr/local/develop /usr/local/develop.bak #备份原有目录链接
$cd xxx
$./configure --prefix=/usr/local/develop/ xxxxx
$make
$sudo make install #安装源码编译的软件
$sudo mv /usr/local/develop /usr/local/backup_installs/develop.xxx #将软件安装目录重命名备份
$sudo mv /usr/local/develop.bak /usr/local/develop #恢复原有所有安装集合链接
$cd /usr/local/backup_installs
$cp -af develop.xxx/* develop.all/ #将新安装的软件合并到安装集合目录中

5 WAIT/FORWARD FAQ [0/8]([0%])

描述该文章中遗留的问题,有待将来解决.

5.1 NEXT 问题1?

  • State "NEXT" from [2016-02-01 一 15:39]

5.2 NEXT 问题2?

  • State "NEXT" from "NEXT" [2016-02-01 一 15:40]

5.3 LATER screen如何将剪切内容与x剪切板关联?

  • State "LATER" from "INBOX" [2016-08-24 三 10:50]

Capture Time:[2016-05-25 三 10:25]


5.4 LATER screenkey

  • State "LATER" from "INBOX" [2016-12-15 四 17:22]

Capture Time:[2016-12-15 四 17:06]

5.5 MAYBE/FUTURE sudo apt-get install screenlets-pack-all screenlets

  • State "MAYBE/FUTURE" from "INBOX" [2016-12-15 四 17:22]

Capture Time:[2016-12-15 四 16:11]

5.6 LATER 如何打开.msg格式的邮件文件

  • State "LATER" from "WAIT/FORWARD" [2016-12-15 四 17:23]
  • State "WAIT/FORWARD" from "INBOX" [2016-12-15 四 17:23]

Capture Time:[2016-08-29 一 17:07]


5.7 LATER sshfs用目录的方式来挂载ssh主机

  • State "LATER" from "WAIT/FORWARD" [2016-12-15 四 17:23]
  • State "WAIT/FORWARD" from "INBOX" [2016-12-15 四 17:23]

Capture Time:[2016-11-17 四 12:11]

NAME
       SSHFS - filesystem client based on ssh

SYNOPSIS
   mounting
       sshfs [user@]host:[dir] mountpoint [options]

   unmounting
       fusermount -u mountpoint

...

5.8 LATER vimdot

  • State "LATER" from [2017-01-06 五 09:29]

可以用dot语言绘制图形的同时,进行预览。

5.9 LATER 跨网传输

  • State "LATER" from "INBOX" [2017-04-07 五 16:18]

Capture Time:[2017-02-22 三 14:22]

直接通过非加密压缩方式,快速传输文件的方式: 1.client on windows(cygwin): nc -l 55555 | tar xzvf -

2.server: tar czvf - <your dir/file> | nc 172.16.246.210 55555

将220上的 test.tgz 直接解压到 215上 直接通过非加密压缩方式,快速传输文件的方式: 1.215 nc -l 55555 | tar xzvf -

2.220 cat test.tgz | nc 172.16.246.215 55555

5.10 WAIT/FORWARD Thunderbird+DavMail 支持Exchange

  • State "WAIT/FORWARD" from [2017-02-27 一 17:20]
    有待整理

Thunderbird 添加 DavMail 支持的方法。另外一种是使用 Exquilla 插件。

缺点是,每次需要先启动 DavMail 才能使用支持 ExchangeThunderbird

refer to: http://karuppuswamy.com/wordpress/2010/05/13/how-to-integrate-thunderbird-with-ms-exchange-to-replace-ms-outlook/

5.10.1 DavMail configuration

5.10.1.1 下载

官网: http://davmail.sourceforge.net/download.html

如下命令下载

$wget --no-check-certificate -c https://downloads.sourceforge.net/project/davmail/davmail/4.7.3/davmail_4.7.3-2438-1_all.deb?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fdavmail%2Ffiles%2Fdavmail%2F&ts=1488180063&use_mirror=excellmedia
$wget -c --no-check-certificate https://excellmedia.dl.sourceforge.net/project/davmail/davmail/4.7.3/davmail_4.7.3-2438-1_all.deb

已下载如下:davmail_4.7.3-2438-1_all.deb

5.10.1.2 安装配置

安装版本为: davmail_4.7.3-2438-1_all.deb

在系统菜单中打开 davmail, 配置项

Exchange Protocol: EWS
OWA(Exchange) URL: https://hqmx.tpvaoc.com/EWS/Exchange.asmx
5.10.1.3 相关端口
  • POP Port: 1110

    Exchange 接收 emails (这里的情况we use this method in our case)

  • IMAP Port: 1143

    Exchange 接收 emails (这里不使用)

  • SMTP Port: 1025

    通过 Exchange 发送 emals

  • Caldav HTTP Port: 1080

    Exchange server 同步 calendar.

  • LDAP Port: 1389

    Exchange server 获取 address book ( Thunderbird 可以使用这个,在我们编辑邮件的时候自动匹配 email 地址)

5.10.1.4 操作
  1. 关闭
    $cat /usr/bin/davmail 
    #!/bin/sh
    #
    # Usage: davmail [</path/to/davmail.properties>]
    #
    export LD_LIBRARY_PATH=/usr/lib/jni
    for i in /usr/share/davmail/lib/*; do export CLASSPATH=$CLASSPATH:$i; done
    exec java -Xmx512M -Dsun.net.inetaddr.ttl=60 -cp /usr/share/davmail/davmail.jar:/usr/share/java/swt.jar:$CLASSPATH davmail.DavGateway "$@" 
    
    $ps aux |grep davmail
    miracle  11780  1.1  1.4 4191188 111672 ?      Sl   11:52   0:08 java -Xmx512M -Dsun.net.inetaddr.ttl=60 -cp /usr/share/davmail/davmail.jar:/usr/share/java/swt.jar::/usr/share/davmail/lib/activation-1.1.1.jar:/usr/share/davmail/lib/commons-codec-1.3.jar:/usr/share/davmail/lib/commons-collections-3.1.jar:/usr/share/davmail/lib/commons-httpclient-3.1.jar:/usr/share/davmail/lib/commons-logging-1.0.4.jar:/usr/share/davmail/lib/htmlcleaner-2.2.jar:/usr/share/davmail/lib/jackrabbit-webdav-2.4.3.jar:/usr/share/davmail/lib/jcharset-1.3.jar:/usr/share/davmail/lib/jcifs-1.3.14.jar:/usr/share/davmail/lib/jdom-1.0.jar:/usr/share/davmail/lib/junit-3.8.1.jar:/usr/share/davmail/lib/log4j-1.2.16.jar:/usr/share/davmail/lib/mail-1.4.3.jar:/usr/share/davmail/lib/slf4j-api-1.3.1.jar:/usr/share/davmail/lib/slf4j-log4j12-1.3.1.jar:/usr/share/davmail/lib/stax-api-1.0.1.jar:/usr/share/davmail/lib/stax2-api-3.1.1.jar:/usr/share/davmail/lib/woodstox-core-asl-4.1.2.jar:/usr/share/davmail/lib/xercesImpl-2.8.1.jar davmail.DavGateway
    miracle  11961  1.6  0.8 3645736 67540 ?       Sl   12:03   0:01 java -Xmx512M -Dsun.net.inetaddr.ttl=60 -cp /usr/share/davmail/davmail.jar:/usr/share/java/swt.jar::/usr/share/davmail/lib/activation-1.1.1.jar:/usr/share/davmail/lib/commons-codec-1.3.jar:/usr/share/davmail/lib/commons-collections-3.1.jar:/usr/share/davmail/lib/commons-httpclient-3.1.jar:/usr/share/davmail/lib/commons-logging-1.0.4.jar:/usr/share/davmail/lib/htmlcleaner-2.2.jar:/usr/share/davmail/lib/jackrabbit-webdav-2.4.3.jar:/usr/share/davmail/lib/jcharset-1.3.jar:/usr/share/davmail/lib/jcifs-1.3.14.jar:/usr/share/davmail/lib/jdom-1.0.jar:/usr/share/davmail/lib/junit-3.8.1.jar:/usr/share/davmail/lib/log4j-1.2.16.jar:/usr/share/davmail/lib/mail-1.4.3.jar:/usr/share/davmail/lib/slf4j-api-1.3.1.jar:/usr/share/davmail/lib/slf4j-log4j12-1.3.1.jar:/usr/share/davmail/lib/stax-api-1.0.1.jar:/usr/share/davmail/lib/stax2-api-3.1.1.jar:/usr/share/davmail/lib/woodstox-core-asl-4.1.2.jar:/usr/share/davmail/lib/xercesImpl-2.8.1.jar davmail.DavGateway
    miracle  12127  0.0  0.0  11116   940 pts/1    S+   12:05   0:00 grep --color=auto davmail
    miracle@xmnb4003210:~$ ps aux |grep davmail |awk '{print $2}'
    11780
    11961
    12130
    
    $kill 11780
    
    $kill 11961
    
5.10.1.5 其它
  1. How to run multiple instances of DavMail ?

    Just create multiple configuration files and provide them as a command line option, see previous question:

    davmail server1.properties
    davmail server2.properties
    

5.10.2 Thunder bird

5.10.2.1 账户设置

新建账户,然后停止自动配置,手动配置如下:

account_thunderbird.png

pop: pop_thunder.png

smtp: smtp_thunder.png

5.10.2.2 文件夹设置

如下: folder_thunderbird.png

5.10.2.3 地址配置

参见: address_thunderbird.png

5.10.2.4 通讯录相关

可地址自动补全等。

参见: address_list_thunder.png

5.10.2.5 日历相关

可创建时间等。

安装 Lightning, 这里是 Lightning 3.3.3

文件->新建->日历,选中保存在网络上

->下一步,格式选中 CalDAV, 位置写: http://localhost:1080/users/miracle.lv@tpv-tech.com/calendar

->下一步,名字是: Works Calendar, Email: Import Identity.

分别参见如下:

calendar1_thunderbird.png

calendar2_thunderbird.png

/home/miracle/mydata/orgmode/data/6ef480dc-678c-4972-b09c-28d524c6ccb4/calendar3_thunderbird.png

5.10.3 问题

5.10.3.1 总是弹出不信任网站是否接受。可以尝试如下:
  1. 尝试1( 不好用?)
    1. 导出证书

      方法比较多,

      比如,登录 https://hqmx.tpvaoc.com/EWS/Exchange.asmx, 在firefox提示的添加例外中,找到导出的菜单,导出相应的证书,文件名假设为 hqmx.tpvaoc.com

      导出的时候,分别尝试导出 chain的方式,以及直接pem的方式.

    2. 添加个人信任证书

      输入如下命令:

      $keytool -import -alias mytpvaoc -keystore /etc/ssl/certs/java/cacerts -trustcacerts -file /home/miracle/work/davcert/hqmx.tpvaoc.com -storepass changeit -noprompt
      
    3. 参考: http://davmail.sourceforge.net/sslsetup.html
      Most users rely on the interactive accept certificate dialog to handle non public certificate authorities. However, this will not work with an Exchange server cluster with a different certificate on each server. In this case, you need to update global Java truststore with the custom certificate authority:
      
      keytool -import -alias root -keystore /path/to/jre/lib/security/cacerts -trustcacerts -file rootca.crt -storepass changeit -noprompt
      
  2. 尝试2(不好用)
    1. 在firefox中访问相关网址: https://tpmail.tpvaoc.com/owa/ 在弹出的安全提示中,添加例外并导出证书。
    2. 在thunderbird, 编辑->首选->高级->证书->查看证书->服务器,导入刚刚的内容。以及添加例外: https://hqmx.tpvaoc.com/EWS/Exchange.asmx

    参见: cert_thunderbird.png

  3. 尝试3(不好用)
    1. 导出证书

    在thunderbird, 编辑->首选->高级->证书->查看证书->服务器,将的证书导出到 tmpTrans/davmail/ 如下: cafile_thunderbird.png

    1. 配置文件 ~/.davmail.properties 修改如下:
    ...
    davmail.ssl.clientKeystoreFile=/home/miracle/tmpTrans/davcert/hqmx.tpvaoc.com
    davmail.ssl.clientKeystorePass=
    davmail.ssl.clientKeystoreType=PKCS11
    ...
    
    1. 重启 davmail, 类似如下,除了最后一个,都kill
    $ ps aux |grep davmail |awk '{print $2}'
    11780
    11961
    12130
    $kill 11780
    $kill 11961
    $davmail (可图形启动)
    

5.11 MAYBE/FUTURE lua geany

  • State "MAYBE/FUTURE" from "INBOX" [2017-04-07 五 16:10]

Capture Time:[2016-12-27 二 17:05]

sudo apt-get install geany-plugin-lua

5.12 MAYBE/FUTURE haroopad

  • State "MAYBE/FUTURE" from "INBOX" [2017-04-07 五 16:17]

Capture Time:[2017-02-20 一 19:35]

markdown 编辑预览。

5.13 LATER 常用linux命令的源码

  • State "LATER" from "INBOX" [2017-04-07 五 16:26]

Capture Time:[2017-03-02 四 09:55]

  1. busybox
  2. coreutils

5.14 LATER mount等linux源码

5.15 LATER shell操作技巧,自动补全上下搜索的技巧

  • State "LATER" from "INBOX" [2017-04-07 五 16:26]

Capture Time:[2017-03-03 五 09:39]

5.16 LATER shell输入实用技巧

  • State "LATER" from "INBOX" [2017-04-07 五 16:26]

Capture Time:[2017-03-03 五 09:58]

Ctrl+Y 粘贴最近的文本 粘贴最近剪切的文本

Alt+Y 粘贴早期的文本 轮回到先前剪切的文本并粘贴它

Ctrl+C 删除整行 删除一整行

ctrl + s 锁住终端

ctrl + q 解锁终端

Ctrl+R 反向渐进搜索 按下这些键后,输入一个搜索字符串进行反向搜索。输入此字符串后,匹配的命令行即会出现,可以运行或编辑它

Ctrl+S 前向渐进搜索 与前一个功能相似,只不过是前向搜索(与锁住终端冲突?)

Alt+P 反向搜索 按下这些键后,输入一个字符串进行反向搜索。输入一个字符串并且按Enter键可看到包含该字符串的最近已用命令

Alt+N 前向搜索 与前一个功能类似,只不过是前向搜索

Keyboard Macros start-kbd-macro (C-x () Begin saving the characters typed into the current keyboard macro. end-kbd-macro (C-x )) Stop saving the characters typed into the current keyboard macro and store the definition. call-last-kbd-macro (C-x e) Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard.

shell上: 0表示标准输入 1表示标准输出 2表示标准错误输出 > 默认为标准输出重定向,与 1> 相同 2>&1 意思是把 标准错误输出 重定向到 标准输出. &>file 意思是把 标准输出 和 标准错误输出 都重定向到文件file中

参考: http://blog.chinaunix.net/uid-361890-id-342066.html

更多信息,参考比较权威的参考:

$man 1 bash
$man history

5.17 MAYBE/FUTURE 关于 configure 系列体系的交叉编译

  • State "MAYBE/FUTURE" from "WAIT/FORWARD" [2017-04-07 五 16:27]
  • State "WAIT/FORWARD" from "INBOX" [2017-04-07 五 16:27]

Capture Time:[2017-03-09 四 10:37] ./configure –prefix=/home/miracle.lv/test/sysroot/usr/local –host=armv7a-mediatek482_001_neon-linux-gnueabi CC=armv7a-mediatek482_001_neon-linux-gnueabi-gcc

5.18 LATER 设置coredump的格式

  • State "LATER" from "INBOX" [2017-04-07 五 16:27]

Capture Time:[2017-03-10 五 14:44]

在masf fvp 系统中:

$echo  /data/coredump/core_%e_sig%s_pid%p > /proc/sys/kernel/core_pattern
$ulimit -c unlimited

5.19 WAIT/FORWARD ssh远程解压

  • State "WAIT/FORWARD" from "INBOX" [2017-04-07 五 16:29]
    wait for arranged.

Capture Time:[2017-04-01 六 10:52]

$ssh <yourname>@172.16.246.220 cat /home/share/miracle/masf_integer_base/masf/fvp_branch_for_sync/_repo_fvp_latest.tgz |tar -xzvf -

5.20 WAIT/FORWARD 每次启动vim或者ssh的时候都会提示错误

  • State "WAIT/FORWARD" from "LATER" [2017-04-07 五 18:48]
    wait for arrange.
  • State "LATER" from "INBOX" [2017-04-07 五 16:32]

Capture Time:[2017-03-31 五 09:30]

vim: /usr/local/develop/lib/libcrypto.so.1.0.0: no version information available (required by /usr/lib/libpython2.7.so.1.0)
vim: /usr/local/develop/lib/libssl.so.1.0.0: no version information available (required by /usr/lib/libpython2.7.so.1.0)
ssh: /usr/local/develop/lib/libcrypto.so.1.0.0: no version information available (required by ssh)

参考: https://www.oschina.net/question/936758_87431

http://stackoverflow.com/questions/18390833/no-version-information-available

$vim openssl.ld
$cat openssl.ld
 OPENSSL_1.0.0 {
             global:
                    *;
 };
$./config --prefix=/usr/local/develop/ --openssldir=/usr/local/develop/openssl shared -Wl,--version-script=$(pwd)/openssl.ld -Wl,-Bsymbolic-functions

5.21 emacs dot绘图出现错误

使用emacs的dot绘图时, C-c C-c 出现如下错误:

Fontconfig warning: "/etc/fonts/conf.d/25-wqy-zenhei.conf", line 11: Having multiple values in <test> isn't supported and may not work as expected
Fontconfig warning: "/etc/fonts/conf.d/41-arphic-ukai.conf", line 16: Having multiple <family> in <alias> isn't supported and may not work as expected
Fontconfig warning: "/etc/fonts/conf.d/41-arphic-ukai.conf", line 16: Having multiple <family> in <alias> isn't supported and may not work as expected
....

5.21.1 实践

直接将相关的字体.conf文件删掉。

5.21.2 参考

http://tieba.baidu.com/p/1849187273

关键点:

安装了最新的fontconfig以后会出现如下警告(如果你安装了wqy字体):

updating font cache... Fontconfig warning: "/etc/fonts/conf.d/44-wqy-microhei.conf", line 6: Having multiple values in <test> isn't supported and may not works as expected
Fontconfig warning: "/etc/fonts/conf.d/65-wqy-zenhei.conf", line 11: Having multiple values in <test> isn't supported and may not works as expected
Fontconfig warning: "/etc/fonts/conf.d/85-wqy-bitmapsong.conf", line 33: Having multiple values in <test> isn't supported and may not works as expected
Fontconfig warning: "/etc/fonts/conf.d/85-wqy-bitmapsong.conf", line 55: Having multiple values in <test> isn't supported and may not works as expected
done.
Fontconfig warning: "/etc/fonts/conf.d/50-user.conf", line 9: reading configurations from ~/.fonts.conf is deprecated.
更正方法是把:
<test qual=”any” name=”family”>
<string>WenQuanYi Micro Hei</string>
<string>文泉驿微米黑</string>
<string>文泉驿微米黑</string>
</test>
改成
<test qual=”any” name=”family”>
<string>WenQuanYi Micro Hei</string>
</test>
<test qual=”any” name=”family”>
<string>文泉驿微米黑</string>
</test>
<test qual=”any” name=”family”>
<string>文泉驿微米黑</string>
</test>
这种形式。
关于
Fontconfig warning: “/etc/fonts/conf.d/50-user.conf”, line 9: reading configurations from ~/.fonts.conf is deprecated.
把50-user.conf里第九行的deprecated对应的“yes”改成“no”。
静·是一种态度: 研究了两天字体才发现,sudo rm最管用!
Fontconfig warning: "/etc/fonts/conf.d/50-user.conf", line 9: reading configurations from ~/.fonts.conf is deprecated.

解决方法:

mkdir $XDG_CONFIG_HOME/fontconfig
mv .fonts.conf $XDG_CONFIG_HOME/fontconfig/fonts.conf
($XDG_CONFIG_HOME = ~/.config)
神马意思呢,fontconfig2 告诉你,它的配置文件路径是符合 XDG 标准的,$HOME 下的 .fonts.conf 快快移到 $XDG_CONFIG_HOME 下吧。 

necomancer: 回复 realasking :cat一下/etc/fonts/conf.d/50-user.conf就会看到的,下面指向~/.fonts.conf的两节是“will be removed in future”

https://bbs.archlinux.org/viewtopic.php?pid=1157957#p1157957

Create a $XDG_CONFIG_HOME/fontconfig directory (if not existing already) and move your ~/.fonts.conf there as fonts.conf.
Usually $XDG_CONFIG_HOME is ~/.config

The warning should then not appear any more.

5.22 /proc/pid/maps 查看动态链接的库

5.23 /proc/pid/environ 查看进程的环境变量

5.24 批量重命名文件的技巧

尝试了半天,终于找到了几种批量重命名文件的方法,记录下来以备后用^_^

[quietheart@lv-k temp]\( touch {1,2,3,4,5}.cpp [quietheart@lv-k temp]\) touch [1-5] [quietheart@lv-k temp]\( ls [1-5] 1.cpp 2.cpp 3.cpp 4.cpp 5.cpp [quietheart@lv-k temp]\) rm \[1-5\] rm:是否删除 一般空文件 “[1-5]”? y [quietheart@lv-k temp]\( ls 1.cpp 2.cpp 3.cpp 4.cpp 5.cpp [quietheart@lv-k temp]\) rename .cpp .c *.cpp [quietheart@lv-k temp]\( ls 1.c 2.c 3.c 4.c 5.c [quietheart@lv-k temp]\) ls *.c |awk '{sub(.c$,"")}{print $1}'|awk '{printf "mv %s.c %s.cpp\n",$1,\(1}' |sh [quietheart@lv-k temp]\) ls 1.cpp 2.cpp 3.cpp 4.cpp 5.cpp [quietheart@lv-k temp]\( ls *.cpp |sed 's/\(.*\).cpp/mv & \1.c/' |sh [quietheart@lv-k temp]\) ls 1.c 2.c 3.c 4.c 5.c

以上过程大致是: 先把所有".cpp"文件的后缀修改成".c"后缀,再把".c"修改回".cpp",再把".cpp"修改成".c"。 原理分别用到了:使用rename、使用awk+sh、使用sed+正则+sh,三种方式。

5.25 链接选项 -rpath-rpath-link

链接动态库

如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用LD_LIBRARY_PATH》)。

不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》 )。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
链接选项和路径

现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式移植时#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过-rpath(或-R )、LD_LIBRARY_PATH指定查找路径。

链接器ld的选项有 -L,-rpath 和 -rpath-link,看了下 man ld,大致是这个意思:

-L: “链接”的时候,去找的目录,也就是所有的 -lFOO 选项里的库,都会先从 -L 指定的目录去找,然后是默认的地方。编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库,如果找不到,还是会报错,类似cannot open shared object file。

-rpath-link:这个也是用于“链接”的时候的,例如你显示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你并没有指定,而是 FOO.so 引用到它,这个时候,会先从 -rpath-link 给的路径里找。

-rpath: “运行”的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找。对于交叉编译,交叉编译链接器需已经配置 –with-sysroot 选项才能起作用。也就是说,-rpath指定的路径会被记录在生成的可执行程序中,用于运行时查找需要加载的动态库。-rpath-link 则只用于链接时查找。
链接搜索顺序

直接man ld。


gcc和链接选项的使用

在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl(是字母l,不是1,我曾多次弄错),以区别不是编译器的选项。

参考: http://blog.csdn.net/xph23/article/details/38157491

5.26 di 命令替代 du 命令

5.27 使用shell数组来实现cut类似功能的技巧

修改一个目录下文件的权限使之和另一个目录文件一样 /3rd/browser_engine/data/3rd/browser_engine

cd /3rd/browser_engine
for file in `find . -type f`; do atrr_file=$(ls -Z "$file"); array=($atrr_file); chcon ${array[0]} /data/3rd/browser_engine/${array[1]}; done