修改/etc/fstab后freebsd无法正常启动的解决方法

在错误地修改了/etc/fstab文件后,freebsd无法正常启动,只能进入单用户模式。
想要把文件改正回去,但此时的vi等编辑器都不能用。
原因是文件系统没有被挂载上,所以正确的解决之道就是把必要的文件系统都手动挂载上。
没管太多,我把根分区/以及/var, /usr等全挂上了:
#mount /
#mount /usr
#mount /var
ok,这样就可以用vi了,改后之后shutdown重启就行了。

— EOF —

FreeBSD 6.0的X环境配置问题

在图书馆借了本《FreeBSD Handbook(第二版)中文版》,照着书里讲的一步步开始安装FreeBSD。

FreeBSD版本是6.0,安装过程中并没有碰到书上提到的X环境的配置,还以为是自己漏掉了什么步骤,于是重新安装。重装过程中仍然没有X环境配置的向导,翻到手册的第5章“X Window系统”,准备手动配置X环境。输入XFree86 -configure,提示命令不存在,这下子郁闷了。在网上搜索了很久,还是没有找到答案。

运气好让我在FreeBSD中文官网上看到了最新的FreeBSD使用手册。里面提到“从FreeBSD 5.3-RELEASE开始,X服务的机制从sysinstall中删掉了。您必须在安装完FreeBSD之后再X服务。”,FT,难怪我找不到配置菜单!

接着以超级用户登录FreeBSD,建立初始的配置文件:
# Xorg -configure
然后输入:
# xorgcfg -textmode
在文本模式下配置X环境。

配置完后运行startx,即可启用X环境。

— EOF —

Linux进程间通信(IPC)学习笔记

IPC:interprocess communication 进程间通信

一、管道:

1. 无名管道:
打开与关闭管道:
#include <unistd.h>
int pipe(int filedes[2]);
filedes[0]用于读出数据,读取时必须关闭写入端,即close(filedes[1]);
filedes[1]用于写入数据,写入时必须关闭读取端,即close(filedes[0])。
2. 有名管道FIFO:
创建FIFO:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
读写管道与读写文件的操作相同。

二、System V FIFO:

1. 共享内存:
创建共享内存区:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int flags);
附加/分离共享内存区:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
char *shmat(int shmid, char *shmaddr, int flags);
int shmdt(char *shmadr);
2. 消息队列:
创建消息队列:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int flags);
读写消息:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *prt, size_t nbytes, int flags);
int msgrcv(int msqid, void *prt, size_t nbytes, int flags);
prt是指向msgbuf结构的指针,msgbuf在中定义如下:
struct msgbuf {
long mtype;
char mtext[1];
};
msgbuf结构可以自由更改设置。
删除消息队列:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int int msgctl(int msqid, int cmd, struct msqid_ds *buf);
cmd为IPC_RMID时为删除队列msqid。
3. 信号量:
创建/打开:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int flags);
int semop(int semid, struct sembuf *semops, unsigned nops);
sembuf结构定义如下:
struct sembuf {
short sem_num; /* Semaphore number */
short sem_op; /* The operation to perform */
short sem_flg; /* Flags controlling the operation */
};
如果sem_op为正,表示资源被释放,信号量增加。
如果sem_op为负,表示资源被申请,信号量减少。
如果sem_op为0,表示进程被阻塞直到信号量变为0。
控制和删除:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, union semun arg);
当cmd为IPC_RMID时为删除信号量集。

— EOF —

gdb调试器命令学习总结笔记

Linux中包含有一个很有用的调试工具--gdb(GNU Debuger),它可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具。

和所有常用的调试工具一样,gdb提供了以下功能:
 # 监视程序中变量的值
 # 在程序中设置断点
 # 程序的单步执行

在使用gdb前,必须先载入可执行文件,因为要进行调试,文件中就必须包含调试信息,所以在用gcc或cc编译时就需要用-g参数来打开程序的调试选项。

调试开始时,必须先载入要进行调试的程序,可以用以下两种方式:
 * 在启动gdb后执行以下命令:
   file 可执行文件路径
 * 在gdb启动时就载入程序:
   gdb 可执行文件路径

载入程序后,接下来就是要进行断点的设置,要监视的变量的添加等工作,下面对在这个过程中常会用到的命令逐一进行介绍:
 * list:显示程序中的代码,常用使用格式有:
    list
      输出从上次调用list命令开始往后的10行程序代码。
    list –
      输出从上次调用list命令开始往前的10行程序代码。
    list n
      输出第n行附近的10行程序代码。
    list function
      输出函数function前后的10行程序代码。
 * forward/search:从当前行向后查找匹配某个字符串的程序行。使用格式:
    forward/search 字符串
  查找到的行号将保存在$_变量中,可以用print $_命令来查看。
 * reverse-search:和forward/search相反,向前查找字符串。使用格式同上。
 * break:在程序中设置断点,当程序运行到指定行上时,会暂停执行。使用格式:
    break 要设置断点的行号
 * tbreak:设置临时断点,在设置之后只起作用一次。使用格式:
    tbreak 要设置临时断点的行号
 * clear:和break相反,clear用于清除断点。使用格式:
    clear 要清除的断点所在的行号
 * run:启动程序,在run后面带上参数可以传递给正在调试的程序。
 * awatch:用来增加一个观察点(add watch),使用格式:
    awatch 变量或表达式
  当表达式的值发生改变或表达式的值被读取时,程序就会停止运行。
 * watch:与awatch类似用来设置观察点,但程序只有当表达式的值发生改变时才会停止运行。使用格 式:
    watch 变量或表达式
  需要注意的是,awatch和watch都必须在程序运行的过程中设置观察点,即可运行run之后才能设置。
 * commands:设置在遇到断点后执行特定的指令。使用格式有:
    commands
      设置遇到最后一个遇到的断点时要执行的命令
    commands n
      设置遇到断点号n时要执行的命令
  注意,commands后面跟的是断点号,而不是断点所在的行号。
  在输入命令后,就可以输入遇到断点后要执行的命令,每行一条命令,在输入最后一条命令后输入end就可以结束输入。
 * delete:清除断点或自动显示的表达式。使用格式:
    delete 断点号
 * disable:让指定断点失效。使用格式:
    disable 断点号列表
  断点号之间用空格间隔开。
 * enable:和disable相反,恢复失效的断点。使用格式:
    enable 断点编号列表
 * ignore:忽略断点。使用格式:
    ignore 断点号 忽略次数
 * condition:设置断点在一定条件下才能生效。使用格式:
    condition 断点号 条件表达式
 * cont/continue:使程序在暂停在断点之后继续运行。使用格式:
    cont
      跳过当前断点继续运行。
    cont n
      跳过n次断点,继续运行。
  当n为1时,cont 1即为cont。
 * jump:让程序跳到指定行开始调试。使用格式:
    jump 行号
 * next:继续执行语句,但是跳过子程序的调用。使用格式:
    next
      执行一条语句
    next n
      执行n条语句
 * nexti:单步执行语句,但和next不同的是,它会跟踪到子程序的内部,但不打印出子程序内部的语句。使用格式同上。
 * step:与next类似,但是它会跟踪到子程序的内部,而且会显示子程序内部的执行情况。使用格式同上。
 * stepi:与step类似,但是比step更详细,是nexti和step的结合。使用格式同上。
 * whatis:显示某个变量或表达式的数据类型。使用格式:
    whatis 变量或表达式
 * ptype:和whatis类似,用于显示数据类型,但是它还可以显示typedef定义的类型等。使用格式:
    ptype 变量或表达式
 * set:设置程序中变量的值。使用格式:
    set 变量=表达式
    set 变量:=表达式
 * display:增加要显示值的表达式。使用格式:
    display 表达式
 * info display:显示当前所有的要显示值的表达式。
 * delete display/undisplay:删除要显示值的表达式。使用格式:
    delete display/undisplay 表达式编号
 * disable display:暂时不显示一个要表达式的值。使用格式:
    disable display 表达式编号
 * enable display:与disable display相反,使用表达式恢复显示。使用格式:
    enable display 表达式编号
 * print:打印变量或表达式的值。使用格式:
    print 变量或表达式
  表达式中有两个符号有特殊含义:$和$$。
  $表示给定序号的前一个序号,$$表示给定序号的前两个序号。
  如果$和$$后面不带数字,则给定序号为当前序号。
 * backtrace:打印指定个数的栈帧(stack frame)。使用格式:
    backtrace 栈帧个数
 * frame:打印栈帧。使用格式:
    frame 栈帧号
 * info frame:显示当前栈帧的详细信息。
 * select-frame:选择栈帧,选择后可以用info frame来显示栈帧信息。使用格式:
    select-frame 栈帧号
 * kill:结束当前程序的调试。
 * quit:退出gdb。

如要查看所有的gdb命令,可以在gdb下键入两次Tab(制表符),运行“help command”可以查看命令command的详细使用格式。
本文仅对使用gdb调试过程中的一些常用指令的用法进行简单地总结,如要获取关于gdb的更详细的资料,请参阅gdb的官方文档:
  http://www.gnu.org/software/gdb/documentation/

— EOF —

vi编辑器常用的命令及快捷键

终于找了个时间把它们整理了出来,以备今后查用。

光标控制命令 

命令                        光标移动
h或^h                    向左移一个字符
j或^j或^n                向下移一行
k或^p                    向上移一行
l或空格                     向右移一个字符
G                        移到文件的最后一行
nG                       移到文件的第n行
w                        移到下一个字的开头
W                        移到下一个字的开头,忽略标点符号
b                        移到前一个字的开头
B                        移到前一个字的开头,忽略标点符号
L                        移到屏幕的最后一行
M                        移到屏幕的中间一行
H                        移到屏幕的第一行
e                        移到下一个字的结尾
E                        移到下一个字的结尾,忽略标点符号
(                        移到句子的开头
)                        移到句子的结尾
{                        移到段落的开头
}                        移到下一个段落的开头
0或|                     移到当前行的第一列
n|                       移到当前行的第n列
^                        移到当前行的第一个非空字符
$                        移到当前行的最后一个字符
+或return                移到下一行的第一个字符
-                        移到前一行的第一个非空字符


在vi中添加文本

命令                         插入动作
a                        在光标后插入文本
A                        在当前行插入文本
i                        在光标前插入文本
I                        在当前行前插入文本
o                        在当前行的下边插入新行
O                        在当前行的上边插入新行
:r file                  读入文件file内容,并插在当前行后
:nr file                 读入文件file内容,并插在第n行后
escape                   回到命令模式
^v char                  插入时忽略char的指定意义,这是为了插入特殊字符


在vi中删除文本

命令                         删除操作
x                        删除光标处的字符,可以在x前加上需要删除的字符数目
nx                       从当前光标处往后删除n个字符
X                        删除光标前的字符,可以在X前加上需要删除的字符数目
nX                       从当前光标处往前删除n个字符
dw                       删至下一个字的开头
ndw                      从当前光标处往后删除n个字
dG                       删除行,直到文件结束
dd                       删除整行
ndd                      从当前行开始往后删除
db                       删除光标前面的字
ndb                      从当前行开始往前删除n字
:n,md                    从第m行开始往前删除n行
d或d$                    从光标处删除到行尾
dcursor_command          删除至光标命令处,如dG将从当产胆行删除至文件的末尾
^h或backspace            插入时,删除前面的字符
^w                       插入时,删除前面的字


修改vi文本

每个命令前面的数字表示该命令重复的次数
命令                         替换操作
rchar                    用char替换当前字符
R text escape            用text替换当前字符直到换下Esc键
stext escape             用text代替当前字符
S或cctext escape         用text代替整行
cwtext escape            将当前字改为text
Ctext escape             将当前行余下的改为text
cG escape                修改至文件的末尾
ccursor_cmd text escape  从当前位置处到光标命令位置处都改为text


在vi中查找与替换

命令                         查找与替换操作
/text                    在文件中向前查找text
?text                    在文件中向后查找text
n                        在同一方向重复查找
N                        在相反方向重复查找
ftext                    在当前行向前查找text
Ftext                    在当前行向后查找text
ttext                    在当前行向前查找text,并将光标定位在text的第一个字符
Ttext                    在当前行向后查找text,并将光标定位在text的第一个字符
:set ic                  查找时忽略大小写
:set noic                查找时对大小写敏感
:s/oldtext/newtext       用newtext替换oldtext
:m,ns/oldtext/newtext    在m行通过n,用newtext替换oldtext
&                        重复最后的:s命令
:g/text1/s/text2/text3   查找包含text1的行,用text3替换text2
:g/text/command          在所有包含text的行运行command所表示的命令
:v/text/command          在所有不包含text的行运行command所表示的命令


在vi中复制文本

命令                         复制操作
yy                       将当前行的内容放入临时缓冲区
nyy                      将n行的内容放入临时缓冲区
p                        将临时缓冲区中的文本放入光标后
P                        将临时缓冲区中的文本放入光标前
dsfsd "(a-z)nyy          复制n行放入名字为圆括号内的可命名缓冲区,省略n表示当前行
"(a-z)ndd                删除n行放入名字为圆括号内的可命名缓冲区,省略n表示当前行
"(a-z)p                  将名字为圆括号的可命名缓冲区的内容放入当前行后
"(a-z)P                  将名字为圆括号的可命名缓冲区的内容放入当前行前


在vi中撤消与重复

命令                         撤消操作
u                        撤消最后一次修改
U                        撤消当前行的所有修改
.                        重复最后一次修改
,                        以相反的方向重复前面的f、F、t或T查找命令
;                        重复前面的f、F、t或T查找命令
"np                      取回最后第n次的删除(缓冲区中存有一定次数的删除内容,一般为9)
n                        重复前面的/或?查找命令
N                        以相反方向重复前面的/或?命令


保存文本和退出vi

命令                         保存和/或退出操作
:w                       保存文件但不退出vi
:w file                  将修改保存在file中但不退出vi
:wq或ZZ或:x              保存文件并退出vi
:q!                      不保存文件,退出vi
:e!                      放弃所有修改,从上次保存文件开始再编辑


vi中的选项

选项                         作用
:set all                 打印所有选项
:set nooption            关闭option选项
:set nu                  每行前打印行号
:set showmode            显示是输入模式还是替换模式
:set noic                查找时忽略大小写
:set list                显示制表符(^I)和行尾符号
:set ts=8                为文本输入设置tab stops
:set window=n            设置文本窗口显示n行


vi的状态

选项                         作用
:.=                      打印当前行的行号
:=                       打印文件中的行数
^g                       显示文件名、当前的行号、文件的总行数和文件位置的百分比
:l                       使用字母"l"来显示许多的特殊字符,如制表符和换行符


在文本中定位段落和放置标记

选项                         作用
{                        在第一列插入{来定义一个段落
[[                       回到段落的开头处
]]                       向前移到下一个段落的开头处
m(a-z)                   用一个字母来标记当前位置,如用mz表示标记z
'(a-z)                   将光标移动到指定的标记,如用'z表示移动到z


在vi中连接行

选项                         作用
J                        将下一行连接到当前行的末尾
nJ                       连接后面n行


光标放置与屏幕调整

选项                         作用
H                        将光标移动到屏幕的顶行
nH                       将光标移动到屏幕顶行下的第n行
M                        将光标移动到屏幕的中间
L                        将光标移动到屏幕的底行
nL                       将光标移动到屏幕底行上的第n行
^e(ctrl+e)               将屏幕上滚一行
^y                       将屏幕下滚一行
^u                       将屏幕上滚半页
^d                       将屏幕下滚半页
^b                       将屏幕上滚一页
^f                       将屏幕下滚一页
^l                       重绘屏幕
z-return                 将当前行置为屏幕的顶行
nz-return                将当前行下的第n行置为屏幕的顶行
z.                       将当前行置为屏幕的中央
nz.                      将当前行上的第n行置为屏幕的中央
z-                       将当前行置为屏幕的底行
nz-                      将当前行上的第n行置为屏幕的底行


vi中的shell转义命令

选项                         作用
:!command                执行shell的command命令,如:!ls
:!!                      执行前一个shell命令
:r!command               读取command命令的输入并插入,如:r!ls会先执行ls,然后读入内容
:w!command               将当前已编辑文件作为command命令的标准输入并执行command命令,如:w!grep all
:cd directory            将当前工作目录更改为directory所表示的目录
:sh                      将启动一个子shell,使用^d(ctrl+d)返回vi
:so file                 在shell程序file中读入和执行命令


vi中的宏与缩写
(避免使用控制键和符号,不要使用字符K、V、g、q、v、*、=和功能键)

选项                         作用
:map key command_seq     定义一个键来运行command_seq,如:map e ea,无论什么时候都可以e移到一个字的末尾来追加文本
:map                     在状态行显示所有已定义的宏
:umap key                删除该键的宏
:ab string1 string2      定义一个缩写,使得当插入string1时,用string2替换string1。当要插入文本时,键入string1然后按Esc键,系统就插入了string2
:ab                      显示所有缩写
:una string              取消string的缩写


在vi中缩进文本

选项                         作用
^i(ctrl+i)或tab          插入文本时,插入移动的宽度,移动宽度是事先定义好的
:set ai                  打开自动缩进
:set sw=n                将移动宽度设置为n个字符
n<<                      使n行都向左移动一个宽度
n>>                      使n行都向右移动一个宽度,例如3>>就将接下来的三行每行都向右移动一个移动宽度

顺带附上vim的用户手册:

http://vcd.gro.clinux.org/doc/usr_toc.html

http://vimdoc.sourceforge.net/htmldoc/

— EOF —