摘要: 優化RandomAccessFile類后完整版代碼
1.BufferedRandomAccessFile.java類
1 package kbps.io; 2 3 import java.io.RandomAccessFile; 4 imp... 閱讀全文
通過擴展RandomAccessFile類使之具備Buffer改善I/O性能
JAVA的文件隨機存取類(RandomAccessFile)的I/O效率較低。通過分析其中原因,提出解決方案。逐步展示如何創建具備緩存讀寫能力的文件隨機存取類,并進行了優化。通過與其它文件訪問類的性能對比,證明了其實用價值。
主體:
開發人員使用RandomAccessFile類時。其I/O性能較之其它常用開發語言的同類性能差距甚遠,嚴重影響程序的運行效率。開發人員迫切需要提高效率,下面分析RandomAccessFile等文件類的源代碼,找出其中的癥結所在,并加以改進優化,創建一個"性/價比"俱佳的隨機文件訪問類BufferedRandomAccessFile。
在改進之前先做一個基本測試:逐字節COPY一個12兆的文件(這里牽涉到讀和寫)。
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
我們可以看到兩者差距約32倍,RandomAccessFile也太慢了。先看看兩者關鍵部分的源代碼,對比分析,找出原因。
1.1.[RandomAccessFile]
public class RandomAccessFile implements DataOutput, DataInput {
public final byte readByte() throws IOException {
int ch = this.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
public native int read() throws IOException;
public final void writeByte(int v) throws IOException {
write(v);
}
public native void write(int b) throws IOException;
}
|
可見,RandomAccessFile每讀/寫一個字節就需對磁盤進行一次I/O操作。
1.2.[BufferedInputStream]
public class BufferedInputStream extends FilterInputStream {
private static int defaultBufferSize = 2048;
protected byte buf[]; // 建立讀緩存區
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
public synchronized int read() throws IOException {
ensureOpen();
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return buf[pos++] & 0xff; // 直接從BUF[]中讀取
}
private void fill() throws IOException {
if (markpos < 0)
pos = 0; /* no mark: throw away the buffer */
else if (pos >= buf.length) /* no room left in buffer */
if (markpos > 0) { /* can throw away early part of the buffer */
int sz = pos - markpos;
System.arraycopy(buf, markpos, buf, 0, sz);
pos = sz;
markpos = 0;
} else if (buf.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
} else { /* grow buffer */
int nsz = pos * 2;
if (nsz > marklimit)
nsz = marklimit;
byte nbuf[] = new byte[nsz];
System.arraycopy(buf, 0, nbuf, 0, pos);
buf = nbuf;
}
count = pos;
int n = in.read(buf, pos, buf.length - pos);
if (n > 0)
count = n + pos;
}
}
|
1.3.[BufferedOutputStream]
public class BufferedOutputStream extends FilterOutputStream {
protected byte buf[]; // 建立寫緩存區
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b; // 直接從BUF[]中讀取
}
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
}
|
可見,Buffered I/O putStream每讀/寫一個字節,若要操作的數據在BUF中,就直接對內存的buf[]進行讀/寫操作;否則從磁盤相應位置填充buf[],再直接對內存的buf[]進行讀/寫操作,絕大部分的讀/寫操作是對內存buf[]的操作。
1.3.小結
內存存取時間單位是納秒級(10E-9),磁盤存取時間單位是毫秒級(10E-3),同樣操作一次的開銷,內存比磁盤快了百萬倍。理論上可以預見,即使對內存操作上萬次,花費的時間也遠少對于磁盤一次I/O的開銷。顯然后者是通過增加位于內存的BUF存取,減少磁盤I/O的開銷,提高存取效率的,當然這樣也增加了BUF控制部分的開銷。從實際應用來看,存取效率提高了32倍。
根據1.3得出的結論,現試著對RandomAccessFile類也加上緩沖讀寫機制。
隨機訪問類與順序類不同,前者是通過實現DataInput/DataOutput接口創建的,而后者是擴展FilterInputStream/FilterOutputStream創建的,不能直接照搬。
2.1.開辟緩沖區BUF[默認:1024字節],用作讀/寫的共用緩沖區。
2.2.先實現讀緩沖。
讀緩沖邏輯的基本原理:
A 欲讀文件POS位置的一個字節。
B 查BUF中是否存在?若有,直接從BUF中讀取,并返回該字符BYTE。
C 若沒有,則BUF重新定位到該POS所在的位置并把該位置附近的BUFSIZE的字節的文件內容填充BUFFER,返回B。
以下給出關鍵部分代碼及其說明:
public class BufferedRandomAccessFile extends RandomAccessFile {
// byte read(long pos):讀取當前文件POS位置所在的字節
// bufstartpos、bufendpos代表BUF映射在當前文件的首/尾偏移地址。
// curpos指當前類文件指針的偏移地址。
public byte read(long pos) throws IOException {
if (pos < this.bufstartpos || pos > this.bufendpos ) {
this.flushbuf();
this.seek(pos);
if ((pos < this.bufstartpos) || (pos > this.bufendpos))
throw new IOException();
}
this.curpos = pos;
return this.buf[(int)(pos - this.bufstartpos)];
}
// void flushbuf():bufdirty為真,把buf[]中尚未寫入磁盤的數據,寫入磁盤。
private void flushbuf() throws IOException {
if (this.bufdirty == true) {
if (super.getFilePointer() != this.bufstartpos) {
super.seek(this.bufstartpos);
}
super.write(this.buf, 0, this.bufusedsize);
this.bufdirty = false;
}
}
// void seek(long pos):移動文件指針到pos位置,并把buf[]映射填充至POS
所在的文件塊。
public void seek(long pos) throws IOException {
if ((pos < this.bufstartpos) || (pos > this.bufendpos)) { // seek pos not in buf
this.flushbuf();
if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0))
{ // seek pos in file (file length > 0)
this.bufstartpos = pos * bufbitlen / bufbitlen;
this.bufusedsize = this.fillbuf();
} else if (((pos == 0) && (this.fileendpos == 0))
|| (pos == this.fileendpos + 1))
{ // seek pos is append pos
this.bufstartpos = pos;
this.bufusedsize = 0;
}
this.bufendpos = this.bufstartpos + this.bufsize - 1;
}
this.curpos = pos;
}
// int fillbuf():根據bufstartpos,填充buf[]。
private int fillbuf() throws IOException {
super.seek(this.bufstartpos);
this.bufdirty = false;
return super.read(this.buf);
}
}
|
至此緩沖讀基本實現,逐字節COPY一個12兆的文件(這里牽涉到讀和寫,用BufferedRandomAccessFile試一下讀的速度):
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedRandomAccessFile |
BufferedOutputStream + DataOutputStream |
2.813 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
可見速度顯著提高,與BufferedInputStream+DataInputStream不相上下。
2.3.實現寫緩沖。
寫緩沖邏輯的基本原理:
A欲寫文件POS位置的一個字節。
B 查BUF中是否有該映射?若有,直接向BUF中寫入,并返回true。
C若沒有,則BUF重新定位到該POS所在的位置,并把該位置附近的 BUFSIZE字節的文件內容填充BUFFER,返回B。
下面給出關鍵部分代碼及其說明:
// boolean write(byte bw, long pos):向當前文件POS位置寫入字節BW。
// 根據POS的不同及BUF的位置:存在修改、追加、BUF中、BUF外等情
況。在邏輯判斷時,把最可能出現的情況,最先判斷,這樣可提高速度。
// fileendpos:指示當前文件的尾偏移地址,主要考慮到追加因素
public boolean write(byte bw, long pos) throws IOException {
if ((pos >= this.bufstartpos) && (pos <= this.bufendpos)) {
// write pos in buf
this.buf[(int)(pos - this.bufstartpos)] = bw;
this.bufdirty = true;
if (pos == this.fileendpos + 1) { // write pos is append pos
this.fileendpos++;
this.bufusedsize++;
}
} else { // write pos not in buf
this.seek(pos);
if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0))
{ // write pos is modify file
this.buf[(int)(pos - this.bufstartpos)] = bw;
} else if (((pos == 0) && (this.fileendpos == 0))
|| (pos == this.fileendpos + 1)) { // write pos is append pos
this.buf[0] = bw;
this.fileendpos++;
this.bufusedsize = 1;
} else {
throw new IndexOutOfBoundsException();
}
this.bufdirty = true;
}
this.curpos = pos;
return true;
}
|
至此緩沖寫基本實現,逐字節COPY一個12兆的文件,(這里牽涉到讀和寫,結合緩沖讀,用BufferedRandomAccessFile試一下讀/寫的速度):
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
BufferedRandomAccessFile |
BufferedOutputStream + DataOutputStream |
2.813 |
BufferedRandomAccessFile |
BufferedRandomAccessFile |
2.453 |
可見綜合讀/寫速度已超越BufferedInput/OutputStream+DataInput/OutputStream。
優化BufferedRandomAccessFile。
優化原則:
- 調用頻繁的語句最需要優化,且優化的效果最明顯。
- 多重嵌套邏輯判斷時,最可能出現的判斷,應放在最外層。
- 減少不必要的NEW。
這里舉一典型的例子:
public void seek(long pos) throws IOException {
...
this.bufstartpos = pos * bufbitlen / bufbitlen;
// bufbitlen指buf[]的位長,例:若bufsize=1024,則bufbitlen=10。
...
}
|
seek函數使用在各函數中,調用非常頻繁,上面加重的這行語句根據pos和bufsize確定buf[]對應當前文件的映射位置,用"*"、"/"確定,顯然不是一個好方法。
優化一:this.bufstartpos = (pos << bufbitlen) >> bufbitlen;
優化二:this.bufstartpos = pos & bufmask; // this.bufmask = ~((long)this.bufsize - 1);
兩者效率都比原來好,但后者顯然更好,因為前者需要兩次移位運算、后者只需一次邏輯與運算(bufmask可以預先得出)。
至此優化基本實現,逐字節COPY一個12兆的文件,(這里牽涉到讀和寫,結合緩沖讀,用優化后BufferedRandomAccessFile試一下讀/寫的速度):
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
BufferedRandomAccessFile |
BufferedOutputStream + DataOutputStream |
2.813 |
BufferedRandomAccessFile |
BufferedRandomAccessFile |
2.453 |
BufferedRandomAccessFile優 |
BufferedRandomAccessFile優 |
2.197 |
可見優化盡管不明顯,還是比未優化前快了一些,也許這種效果在老式機上會更明顯。
以上比較的是順序存取,即使是隨機存取,在絕大多數情況下也不止一個BYTE,所以緩沖機制依然有效。而一般的順序存取類要實現隨機存取就不怎么容易了。
需要完善的地方
提供文件追加功能:
public boolean append(byte bw) throws IOException {
return this.write(bw, this.fileendpos + 1);
}
|
提供文件當前位置修改功能:
public boolean write(byte bw) throws IOException {
return this.write(bw, this.curpos);
}
|
返回文件長度(由于BUF讀寫的原因,與原來的RandomAccessFile類有所不同):
public long length() throws IOException {
return this.max(this.fileendpos + 1, this.initfilelen);
}
|
返回文件當前指針(由于是通過BUF讀寫的原因,與原來的RandomAccessFile類有所不同):
public long getFilePointer() throws IOException {
return this.curpos;
}
|
提供對當前位置的多個字節的緩沖寫功能:
public void write(byte b[], int off, int len) throws IOException {
long writeendpos = this.curpos + len - 1;
if (writeendpos <= this.bufendpos) { // b[] in cur buf
System.arraycopy(b, off, this.buf, (int)(this.curpos - this.bufstartpos),
len);
this.bufdirty = true;
this.bufusedsize = (int)(writeendpos - this.bufstartpos + 1);
} else { // b[] not in cur buf
super.seek(this.curpos);
super.write(b, off, len);
}
if (writeendpos > this.fileendpos)
this.fileendpos = writeendpos;
this.seek(writeendpos+1);
}
public void write(byte b[]) throws IOException {
this.write(b, 0, b.length);
}
|
提供對當前位置的多個字節的緩沖讀功能:
public int read(byte b[], int off, int len) throws IOException {
long readendpos = this.curpos + len - 1;
if (readendpos <= this.bufendpos && readendpos <= this.fileendpos ) {
// read in buf
System.arraycopy(this.buf, (int)(this.curpos - this.bufstartpos),
b, off, len);
} else { // read b[] size > buf[]
if (readendpos > this.fileendpos) { // read b[] part in file
len = (int)(this.length() - this.curpos + 1);
}
super.seek(this.curpos);
len = super.read(b, off, len);
readendpos = this.curpos + len - 1;
}
this.seek(readendpos + 1);
return len;
}
public int read(byte b[]) throws IOException {
return this.read(b, 0, b.length);
}
public void setLength(long newLength) throws IOException {
if (newLength > 0) {
this.fileendpos = newLength - 1;
} else {
this.fileendpos = 0;
}
super.setLength(newLength);
}
public void close() throws IOException {
this.flushbuf();
super.close();
}
|
至此完善工作基本完成,試一下新增的多字節讀/寫功能,通過同時讀/寫1024個字節,來COPY一個12兆的文件,(這里牽涉到讀和寫,用完善后BufferedRandomAccessFile試一下讀/寫的速度):
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
BufferedRandomAccessFile |
BufferedOutputStream + DataOutputStream |
2.813 |
BufferedRandomAccessFile |
BufferedRandomAccessFile |
2.453 |
BufferedRandomAccessFile優 |
BufferedRandomAccessFile優 |
2.197 |
BufferedRandomAccessFile完 |
BufferedRandomAccessFile完 |
0.401 |
與JDK1.4類MappedByteBuffer+RandomAccessFile的對比?
JDK1.4提供了NIO類 ,其中MappedByteBuffer類用于映射緩沖,也可以映射隨機文件訪問,可見JAVA設計者也看到了RandomAccessFile的問題,并加以改進。怎么通過MappedByteBuffer+RandomAccessFile拷貝文件呢?下面就是測試程序的主要部分:
RandomAccessFile rafi = new RandomAccessFile(SrcFile, "r");
RandomAccessFile rafo = new RandomAccessFile(DesFile, "rw");
FileChannel fci = rafi.getChannel();
FileChannel fco = rafo.getChannel();
long size = fci.size();
MappedByteBuffer mbbi = fci.map(FileChannel.MapMode.READ_ONLY, 0, size);
MappedByteBuffer mbbo = fco.map(FileChannel.MapMode.READ_WRITE, 0, size);
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
byte b = mbbi.get(i);
mbbo.put(i, b);
}
fcin.close();
fcout.close();
rafi.close();
rafo.close();
System.out.println("Spend: "+(double)(System.currentTimeMillis()-start) / 1000 + "s");
|
試一下JDK1.4的映射緩沖讀/寫功能,逐字節COPY一個12兆的文件,(這里牽涉到讀和寫):
讀 |
寫 |
耗用時間(秒) |
RandomAccessFile |
RandomAccessFile |
95.848 |
BufferedInputStream + DataInputStream |
BufferedOutputStream + DataOutputStream |
2.935 |
BufferedRandomAccessFile |
BufferedOutputStream + DataOutputStream |
2.813 |
BufferedRandomAccessFile |
BufferedRandomAccessFile |
2.453 |
BufferedRandomAccessFile優 |
BufferedRandomAccessFile優 |
2.197 |
BufferedRandomAccessFile完 |
BufferedRandomAccessFile完 |
0.401 |
MappedByteBuffer+ RandomAccessFile |
MappedByteBuffer+ RandomAccessFile |
1.209 |
確實不錯,如果以后采用1.4版本開發軟件時,需要對文件進行隨機訪問,建議采用MappedByteBuffer+RandomAccessFile的方式。但鑒于目前采用JDK1.3及以前的版本開發的程序占絕大多數的實際情況,如果您開發的JAVA程序使用了RandomAccessFile類來隨機訪問文件,并因其性能不佳,而擔心遭用戶詬病,請試用本文所提供的BufferedRandomAccessFile類,不必推翻重寫,只需IMPORT 本類,把所有的RandomAccessFile改為BufferedRandomAccessFile,您的程序的性能將得到極大的提升,您所要做的就這么簡單。
未來的考慮
讀者可在此基礎上建立多頁緩存及緩存淘汰機制,以應付對隨機訪問強度大的應用。
(完整代碼見下篇)
我爸和我后母結婚的時候,我讀初二。我后母比我爸小了整整十五歲……最初是我爸的下屬,死不要臉地追我爸,我爸的確是比較有魅力的那種男人,但是她也是特別地不要臉,知道別人是有婦之夫還要追……后來我爸媽離婚,她就跟我爸結了婚……一句話,她就是一個不折不扣的二奶,不過比二奶還要無恥一點,是晉級了的二奶……自從他們結了婚,我的生活里除了上學,主要的事情就是對付我后媽……她讓我媽不好過,這些年我也沒讓她太爽……我的腦子有一半的力氣都花在惡作劇上了…… 惡作劇一 偷偷用洗碗的鐵絲球劃她的絲襪,而且還是專門挑收在衣櫥里絲襪抽屜的劃,因為那些絲襪都是貴的幾百塊一雙的那種。每次就劃開兩三條絲,剛開始,她都不知道是我劃壞的。 惡作劇二 用針和剪刀把她的衣服拆線。特別是上衣的腋部和長褲的襠部。而且都是拆里面的那層隱線,穿的時候根本看不出來,但是一穿,一走動,線馬上就開了。哈哈,看見那個無恥的婊 子穿著露內褲的長褲去跟客戶談判,我心里爽的要死!我還在她內衣上動過手腳,讓她一整天背后都垂著一條bra帶在公司里跑來跑去!我不只一次看見她因為衣服脫線而氣急敗壞,還曾經拿著衣服去商店投訴過。 后來有一次,她買了一件貴的大衣,將近八千多,我在屋里聽到她和同事電話說起這件衣服,就留心想:這件衣服我一定要把它弄壞弄到補都不能補。我把那件純白色毛料的大衣的背部放在煤氣上燒……燒出了一個大洞。當時我就知道這么一來她肯定就知道以前的事情也是我干的了,但是還是義無反顧地做了,做的時候心理很有一種悲壯的感覺,覺得自己在給我媽出氣。那種視死如歸的感覺到現在都還記得。 這件事把我后母幾乎氣得抓狂,告訴我爸,我爸把我痛揍了一頓……那天晚上我整晚上都沒睡覺,在臥室里把門反鎖著,趴在窗戶前面大聲哭……還用書卷了個喇叭對著哭……哭聲把半個小區的人都驚動了……后來我每次惹了我后母,她罵我一句,我一聲不坑就地跑到窗戶邊哭……后來我和小區的幾個同齡女孩子混熟了,經常在花壇邊跳皮筋,大家都知道了我有個后媽,而且這個后媽還是“當狐貍精”搶別人的老公來的,小女孩子們回家都跟父母說,小區的人都很同情我……特別是那些老太太,有時候我放學回來看見了,在門口買菜的中年婦女看見了就要議論一句“這孩子學習還特別好呢,可惜了……”當然,我后媽的名聲因此在小區變得特別臭,連開電梯的阿姨都鄙視她…… 惡作劇三 在她的香水里偷偷加鹽或者味精或者雪碧其它什么東西……反正加了看不大出來的那種亂七八糟的東西……我有次上化學實驗還讓男生偷偷給我弄了點高錳酸鉀,就是做氧氣那個……后來也沒敢放,因為膽子還小,怕放了中毒什么的我就慘了……我還想過往她香水里倒點尿之類的,后來自己覺得怪惡心,就也沒有付諸實施…… 惡作劇四 自從跟了我后媽,我的衣服和鞋子都變得特別容易破……尤其是球鞋和襪子,經常是前面一個大破洞……我們上機房都是要換鞋的,每次我換鞋的時候就露出破破爛爛的襪子……我的同學緣很好,每次我同學他們就非常氣憤,詛咒“那個死女人”(好朋友們都這么稱呼我后媽)不得好死……我爸看了很氣,就經常拿錢給我去買鞋買衣服……然后他當然也不知道物品的價錢,每次都胡亂給了不少錢……我攢上兩三次多半就能攢個六七百,然后去商場買東西孝敬我媽或者我奶奶……我奶奶問我哪里來的錢,我就說我爸給我買鞋子的……我奶奶看看我的穿戴,就覺得我特別孝順懂事,然后就大罵一通我后媽是狐貍精,然后會帶著我去商店給我買衣服買鞋……反正我是賺回來了…… 我后媽和我爸后來就經常吵架,因為我奶奶很厭惡她,而且如果親家母遇到了,我奶奶對她媽也很不客氣……當然這里面很大的功勞都歸功于我在中間用各種方式煽風點火……讓我奶奶總覺得我在家特別受虐待……不過我后母對我本來就不好…… 惡作劇五 中學的時候住家里,我經常把家里的設施故意弄壞……比如往下水道倒剩菜,用過的衛生巾直接扔到抽水馬桶里,開了冰箱就不關(當然要趕在父母下班前關上),夏天里把空調開到二十四五度,然后裹著棉被睡覺(為了把空調往死里用,用壞最好),吃飯的時候,我后媽炒完菜,我經常失手打翻……我后媽罵我,我就說:“我又不知道……我又不是故意的……你干嗎這么挑剔……”我后媽如果說:“你有這么笨嗎?一個盤子都拿不住嗎?”我就說:“我就是笨啊,女兒都遺傳爸爸的,你問我爸去啊?”她如果說:“我上次不是說了嗎?剩菜不能倒在下水道里!你就是故意的。”我就說:“我不記得了啊!順手就倒了!隨便你啊,你看我不順眼,當然覺得我是故意的羅!”每次都把她噎得半死。但是有客人在家,我就會特別老實……我后媽讓做什么就做什么,而且經常用眼睛瞟她,裝得很怕她的樣子……我現在想起來覺得我真是天生當演員的料……那么小的年紀就知道做虛弄假……所以我們家親戚朋友都覺得我很乖……我估計如果我后媽跟人說我在家里怎么怎么使壞,他們肯定會想“怪不得人家說后媽的孩子可憐,怪不得她那么怕你呢……” 惡作劇六 我初三的時候參加市里的新概念作文,得了一等獎,里面寫的是我媽,里面就寫了家庭變故,就是第三者插足,后來父母離婚,那個第三者嫁給了我爸等等,那作文寫得很煽情……我在班上念,我們班同學聽得熱淚盈眶的說,要是放在現在,也算是篇悲情小說了……期中考試我考了年級第一,家長會上先是前三名家長介紹經驗,我爸和別的家長滿面春風地介紹了一通……然后是學生的成果展和節目表演……我的節目就是念我那篇獲獎作文……我在上面念,下面眾目睽睽地聽,念到后面,家長們都在下面竊竊私語,我爸和我后媽在下面聽得臉一陣紅一陣白……當時很痛快,代價就是我回家又被我爸痛揍一頓…… 惡作劇七 我現在想起來,那時候很有點肆無忌憚的意思,我爸雖然有時候痛揍我,不過因為他就我一個女兒(我后媽怕影響體形,不肯生孩子),所以心里還是很疼我的說,而且我學習一向很好,年年被評市三好,初中和高中的時候還被評過省三好……后來又保送上了一個好大學……所以總的來說還是比較縱容我的……我的要求基本是有求必應……我小時候很尊敬我爸,但是都是因為他和我媽的事情,我的心里一直有疙瘩……有時候我是很想原諒他,但是人的心理是這樣的,理智有的時候真的很難控制感情……我媽后來一直沒有結婚,一個人住著一套舊房子,每次我想起我媽,我對我爸就根本愛不起來。 -我上大學的時候,花錢很厲害……因為我覺得不花白不花,我爸的錢我不花那個女人也要花……我畢業以后才知道隔壁班的同學稱我每次都是“**(專業)班的那個頭號富婆”……那時候我每個月生活費經常七八千都打不住……還不算作平時過生日出去旅游之類的花銷……我放假回家,一家人出去吃飯,我后媽諷刺我說:“你讀書怎么每個月花那么多錢?都快趕上我工資了”我就頂嘴說:“我花錢關你屁事,你嫁我爸不就是看上他的錢“,一點都不顧忌。我后媽罵我沒家教,我就說我再沒家教也不去泡別人的老公。把邊上的服務小姐聽得一愣一愣的,特別解恨。我在家給我媽打電話,每次都故意當著他們的面說將來我結了婚出國什么什么的肯定把她帶著,以后要讓我媽過好日子,以后過得比誰都舒服。反正是什么話刺激他們就專挑什么話。 我在家的時候,就什么都對著她干……比如我自己有自己的化妝品……但是每次都狠用她的……尤其是香水精華油之類……后來我每次回家,她就得把自己得化妝品收回臥室……每次出門還得把臥室鎖著……晚上她睡覺前要跑步,我看看時間差不多了就趕快上跑步機,邊看電視邊跑……結果每年放假回家都要瘦一圈……因為我存心霸占跑步機……她總不能把我硬趕下來……后來我一回家,她就只好去健身房辦卡,雖然家里有跑步機這。我bf是學醫的,我還想過不少回弄點激素什么的涂在她的維生素丸或者花粉里……讓她怎么保持都會象豬一樣胖起來。不過我還算仁慈了,沒有付諸實施……我后母當然每次都跟我罵罵咧咧,不過我就當沒聽見好了……反正我又不能掉塊肉,可是自己解氣,我算是狠賺的,我連我爸的巴掌都不怕,怕她個鳥。 剛上大學的時候,我忘記從哪里看到的一個狠辦法,如果把我爸和后媽床頭柜里的套套戳幾個洞……但是我找到他們用的套套才發現套套是有包裝袋的,如果我拆開了戳洞他們肯定會發現……結果不了了之……那個想法有點太弱智了……不知道哪個混蛋想出來的……無恥的二奶,不要臉的第三者,我恨她!
歷史上最愚蠢的八大事件
1.1971年,一位亞利桑那人開槍打傷了自己。這倒沒有什么可大驚小怪的,這種事情時有發生。可是為了提高呼救聲的分貝,這位受傷的人又開了一槍,打中了另外一條腿。 2.一位在競選活動的民意調查中落后的日本政客,為了獲得同情的支持選票,制造出被人暗殺的假象。為了使暗殺看上去確有其事,這位政客用刀在自己腿上砍了一刀。沒想到砍斷了動脈,血流如注。在發表最后的競選演說之前,他就一命嗚呼。 3.17世紀的西班牙國王菲利普三世因發燒而去世,他的高燒是由于長時間坐在爐火旁而引起的。 既然他知道溫度高,可為什么不從爐火那里移開呢?原因是:那不是他作為國王的工作。宮廷里負責照看爐火的傭人沒有上班這名傭人的工作就是把國王的座椅往后拉。 4.一個法國人1998年嘗試一次復雜的自殺。他站在一個高高的懸崖上,在脖子上套上一個索套,把繩索固定在一塊巨大的巖石上。然后他喝下了毒藥,并開始自殺懸崖上跳下去的時候,他又朝著自己的腦袋開了一槍。 結果是:子彈沒有打中目標,反而打穿了繩索,因此他掉到了海里而沒能吊死。冰冷的海水撲滅了他衣服上的火焰,而且這種沖擊力使他把毒藥嘔吐出來。 一位漁民把他從水里拖了起來,送到醫院,結果他由于體溫過低而死亡。 5.1932年洛杉磯奧運會。當法國的朱利?內爾打破了鐵餅的奧運會紀錄時,他那獲勝的一擲被判無效并非他違反了任何比賽規則,而是因為所有本應該注視著鐵餅比賽的裁判員都轉過頭去觀看撐桿跳高了。 6.在投籃秒表出現之前,伊利諾伊州有過這樣一場比賽:比賽開始不久,喬治城隊罰球得了一分,接著他們就把球藏起來了,霍馬隊的隊員毫無辦法,只好在球場上席地而坐,而裁判則在看報紙。當比賽時間結束時,喬治城隊開始慶祝他們1:0的勝利。 7.一位烏克蘭商人給他的50名員工每人買了一個傳呼機作為禮物。在他返回的路上,這50個傳呼機同時叫了起來,他由于受驚過度以至于把車撞到電線桿上。 檢查完傷勢之后,他開始查看傳呼機上的信息。只見這50個傳呼機上出現了同一句話:“感謝購買本機!” 8.1968年,底特律的一個竊賊帶著他的愛犬入室行竊。當警察發現時,竊賊倉皇逃走,卻把愛犬留在后面。警察非常容易地就抓住了竊賊,因為他們只是對狗說了句:“回家,寶貝!”
listner.log如果達到2G,數據庫將無法建立連接。 解決辦法有兩個: 1) 用script定期切換日志 2) 設置log_status 現給出第二種方法: 1) 以oracle身份進入linux 2) lsnrctl 3) set log_status off 4) save_config 完成,listner.log不會再漲了。
以oracle 用戶登陸,允許sqlplus "sys/oracle as sysdba"
1.shutdown abort
2.startup nomount pfile=/home/oracle/admin/shlbs/pfile/initshlbs.ora
3.如果startup nomount正常則 重做控制文件 CREATE CONTROLFILE REUSE DATABASE "SHLBS" NORESETLOGS ARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 454 LOGFILE GROUP 1 '/home/oracle/oradata/shlbs/redo01.log' SIZE 100M,GROUP 2 '/home/oracle/oradata/shlbs/redo02.log' SIZE 100M,GROUP 3 '/home/oracle/oradata/shlbs/redo03.log' SIZE 100M DATAFILE '/home/oracle/oradata/shlbs/CITYMGR.dbf','/home/oracle/oradata/shlbs/cwmlite01.dbf','/home/oracle/oradata/shlbs/drsys01.dbf','/home/oracle/oradata/shlbs/example01.dbf','/home/oracle/oradata/shlbs/indx01.dbf','/home/oracle/oradata/shlbs/LBS.dbf','/home/oracle/oradata/shlbs/odm01.dbf','/home/oracle/oradata/shlbs/system01.dbf','/home/oracle/oradata/shlbs/tools01.dbf','/home/oracle/oradata/shlbs/undotbs01.dbf','/home/oracle/oradata/shlbs/users01.dbf','/home/oracle/oradata/shlbs/xdb01.dbf' CHARACTER SET ZHS16GBK
4.如果需要,重做口令文件 orapwd file=口令文件路徑和文件名 password=test entries=2
5.如果重做控制文件成功,則恢復數據庫 recover database;
以上操作具體參數可能和具體數據相關,請修改。
linux聯盟原創www.xxlinux.com www.linuxunion.org轉貼請標明出處 作者上上智
看了這么久的blog,我自寫一點配置哈 現在有很多想學習linux的人, 就是因為不能配置上網,所以不想學習現在我從adsl配置到nat全過程如下: 1)安裝rp-pppoe-3.5-2包 在安裝系統時,對新用戶一般選擇全部安裝的,那就安裝了,以后rpm, 或者tarball了,這很方便,對初學者: eg: rpm -ivh rp-pppoe-3.5-2.rpm tarball 安裝: tar zxvf rp-pppoe-3.5-2.tar.gz cd rp-pppoe-3.5-2 ./configure make make install 2)rp-pppoe-3.5-2配置 步驟: a) adsl-setup 出現: Welcome to the ADSL client setup. First, I will run some checks on your system to make sure the PPPoE client is installed properly... The following DSL config was found on your system: Device: Name: ppp0 Please enter the device if you want to configure the present DSL config (default ppp0) or enter 'n' if you want to create a new one: //這是我已經安裝過了,主要是寫文檔:選擇默認按回車 LOGIN NAME Enter your Login Name (default lanlgn409ldj@zgcnc): //這是我已經安裝過了,:沒有安裝是輸入adsl用戶名 INTERFACE Enter the Ethernet interface connected to the ADSL modem For Solaris, this is likely to be something like /dev/hme0. For Linux, it will be ethX, where 'X' is a number. (default eth0): //選擇默認按回車 Do you want the link to come up on demand, or stay up continuously? If you want it to come up on demand, enter the idle time in seconds after which the link should be dropped. If you want the link to stay up permanently, enter 'no' (two letters, lower-case.) NOTE: Demand-activated links do not interact well with dynamic IP addresses. You may have some problems with demand-activated links. Enter the demand value (default no): //選擇默認按回車 DNS Please enter the IP address of your ISP's primary DNS server. If your ISP claims that 'the server will provide dynamic DNS addresses', enter 'server' (all lower-case) here. If you just press enter, I will assume you know what you are doing and not modify your DNS setup. Enter the DNS information here: // 輸入server自動得到dns,server的ip PASSWORD Please enter your Password:
USERCTRL Please enter 'yes' (two letters, lower-case.) if you want to allow normal user to start or stop DSL connection (default yes): //選擇默認按回車問你是否連接 Please choose the firewall rules to use. Note that these rules are very basic. You are strongly encouraged to use a more sophisticated firewall setup; however, these will provide basic security. If you are running any servers on your machine, you must choose 'NONE' and set up firewalling yourself. Otherwise, the firewall rules will deny access to all standard servers like Web, e-mail, ftp, etc. If you are using SSH, the rules will block outgoing SSH connections which allocate a privileged source port. The firewall choices are: 0 - NONE: This script will not set any firewall rules. You are responsible for ensuring the security of your machine. You are STRONGLY recommended to use some kind of firewall rules. 1 - STANDALONE: Appropriate for a basic stand-alone web-surfing workstation 2 - MASQUERADE: Appropriate for a machine acting as an Internet gateway for a LAN Choose a type of firewall (0-2): //是否設置firwall Do you want to start this connection at boot time? Please enter no or yes (default no): //啟動時是否連接 Do you want to start this connection at boot time? Please enter no or yes (default no): ** Summary of what you entered ** Ethernet Interface: eth0 User name: lanlgn409ldj@zgcnc Activate-on-demand: No DNS: Do not adjust Firewalling: NONE User Control: yes Accept these settings and adjust configuration files (y/n)? //是否寫入配置文件里 選擇 y 3)假如你是用別人的mac連接 1 redhat9.0改mac: ifconfig eth0 down ifconfig eth0 hw ether 5254ab323d51 ifconfig eth0 up ifup ppp0 2 fedora 4.0改mac: ifdown eth0 ifconfig eth0 hw ether 5254ab323d51 ifup eth0 ifup ppp0 & adsl-start 4)測試一下 ping modprobe ip_tables modprobe ip_nat_ftp modprobe ip_nat_irc modprobe ip_conntrack modprobe ip_conntrack_ftp modprobe ip_conntrack_irc /sbin/iptables -F /sbin/iptables -X /sbin/iptables -Z /sbin/iptables -F -t nat /sbin/iptables -X -t nat /sbin/iptables -Z -t nat /sbin/iptables -P INPUT ACCEPT /sbin/iptables -P OUTPUT ACCEPT /sbin/iptables -P FORWARD ACCEPT /sbin/iptables -t nat -P PREROUTING ACCEPT /sbin/iptables -t nat -P POSTROUTING ACCEPT /sbin/iptables -t nat -P OUTPUT ACCEPT /sbin/iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE//不是adsl也可以把ppp0改成eth0 , 1一般網卡nat: [root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=dhcp BROADCAST=192.168.0.255 IPADDR=192.168.0.1 NETMASK=255.255.255.0 NETWORK=192.168.0.0 ONBOOT=yes [root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth0:0 DEVICE=eth0:0 BOOTPROTO=static BROADCAST=192.168..255 IPADDR=192.168.1.2 NETMASK=255.255.255.0 NETWORK=192.168..0 ONBOOT=yes 2 兩塊網卡nat: 只是那個 eth0:0 改成了 eth1 而已啦,其它都是一樣的設置 6)dns 設置 在里面/etc/resolv.conf 把你的ip寫入里面去 nameserver 192.168.0.1 然后重啟要不然,客戶機不能上網
問題引發: 服務器每天產生大量的系統日志,查詢日志,目前日志這塊沒有人專門拿出來做分析,處理這些日志.隨著時間以及服務器訪問量的與日俱增,不小心就會出現硬盤被日志文件占滿的現象.如果刪除這些日志,以后日志分析也許要用到.不刪現有服務會受到影響.以后可能會專門有一臺服務器來處理這些日志,分析日志,估算出性能瓶頸,以及得出相應的有價值的商業信息.所以只能臨時處理一下. 看了一下linux的壓縮格式好多種,忽然一看有些暈,發一篇關于linux壓縮文件的詳細文章,摘自:Unix愛好者家園unix-cd.com ,以下是原文 對于剛剛接觸 Linux 的人來說,一定會給 Linux 下一大堆各式各樣的文件名給搞暈。別個不說,單單就壓縮文件為例,我們知道在 Windows 下最常見的壓縮文件就只有兩種,一是 .zip,另一個是 .rar。可是 Linux 就不同了,它有.gz、.tar.gz、tgz、bz2、.Z、.tar 等眾多的壓縮文件名,此外 windows 下的 .zip 和 .rar 也可以在 Linux 下使用,不過在 Linux 使用 .zip 和 .rar 的人就太少了。 在具體總結各類壓縮文件之前呢,首先要弄清兩個概念:打包和壓縮。打包是指將一大堆文件或目錄什么的變成一個總的文件,壓縮則是將一個大的文件通過一些壓縮算法變成一個小文件。為什么要區分這兩個概念呢?其實這源于 Linux 中的很多壓縮程序只能針對一個文件進行壓縮,這樣當你想要壓縮一大堆文件時,你就得先借助另它的工具將這一大堆文件先打成一個包,然后再就原來的壓縮程序進行壓縮。 Linux下最常用的打包程序就是 tar 了,使用 tar 程序打出來的包我們常稱為 tar 包,tar 包文件的命令通常都是以 .tar 結尾的。生成 tar 包后,就可以用其它的程序來進行壓縮了,所以我們先了解一下 tar 命令的基本用法: tar 命令的選項有很多(用man tar可以查看到),但我們通常需要的就是那么幾個: # tar -cf all.tar *.jpg 這條命令是將所有 .jpg 的文件打成一個名為 all.tar 的包。-c 是表示產生新的包,-f 指定包的文件名。 # tar -rf all.tar *.gif 這條命令是將所有.gif的文件增加到 all.tar 的包里面去。-r 是表示增加文件的意思。 # tar -uf all.tar logo.gif 這條命令是更新原來 tar 包 all.tar 中 logo.gif 文件,-u是表示更新文件的意思。 # tar -tf all.tar 這條命令是列出 all.tar 包中所有文件,-t 是列出文件的意思 # tar -xf all.tar 這條命令是解出 all.tar 包中所有文件,-t 是解開的意思 以上就是 tar 的最基本的用法。為了方便用戶在打包解包的同時可以壓縮或解壓文件,tar 提供了一種特殊的功能。這就是 tar 可以在打包或解包的同時調用其它的壓縮程序,比如調用 gzip、bzip2 等。 (一)、 tar 調用 gzip gzip 是 GNU 組織開發的一個壓縮程序,.gz 結尾的文件就是 gzip 壓縮的結果。與 gzip 相對的解壓程序是 gunzip。tar 中使用 -z 這個參數來調用 gzip。下面來舉例說明一下: # tar -czf all.tar.gz *.jpg 這條命令是將所有 .jpg 的文件打成一個 tar 包,并且將其用 gzip 壓縮,生成一個 gzip 壓縮過的包,包名為 all.tar.gz。 # tar -xzf all.tar.gz 這條命令是將上面產生的包解開。 (二)、 tar 調用 bzip2 bzip2 是一個壓縮能力更強的壓縮程序,.bz2 結尾的文件就是 bzip2 壓縮的結果。與 bzip2 相對的解壓程序是 bunzip2。tar 中使用-j這個參數來調用 gzip。下面來舉例說明一下: # tar -cjf all.tar.bz2 *.jpg 這條命令是將所有 .jpg 的文件打成一個 tar 包,并且將其用 bzip2 壓縮,生成一個 bzip2 壓縮過的包,包名為 all.tar.bz2。 # tar -xjf all.tar.bz2 這條命令是將上面產生的包解開。 (三)、 tar 調用 compress compress 也是一個壓縮程序,但是好象使用 compress 的人不如 gzip 和 bzip2 的人多。.Z 結尾的文件就是 bzip2 壓縮的結果。與 compres s相對的解壓程序是 uncompress。tar 中使用 -Z 這個參數來調用 gzip。下面來舉例說明一下: # tar -cZf all.tar.Z *.jpg 這條命令是將所有 .jpg 的文件打成一個 tar 包,并且將其用 compress 壓縮,生成一個 uncompress 壓縮過的包,包名為 all.tar.Z # tar -xZf all.tar.Z 這條命令是將上面產生的包解開 有了上面的知識,你應該可以解開多種壓縮文件了,下面對于 tar 系列的壓縮文件作一個小結: (一)、對于 .tar 結尾的文件 tar -xf all.tar (二)、對于 .gz 結尾的文件 gzip -d all.gz gunzip all.gz (三)、對于 .tgz 或 .tar.gz 結尾的文件 tar -xzf all.tar.gz tar -xzf all.tgz (四)、對于 .bz2 結尾的文件 bzip2 -d all.bz2 bunzip2 all.bz2 (五)、對于 tar.bz2 結尾的文件 tar -xjf all.tar.bz2 (六)、對于 .Z 結尾的文件 uncompress all.Z (七)、對于.tar.Z結尾的文件 tar -xZf all.tar.z 另外對于 Window 下的常見壓縮文件 .zip 和 .rar,Linux 也有相應的方法來解壓它們: (1)對于 .zip linux 下提供了 zip 和 unzip 程序,zip 是壓縮程序,unzip 是解壓程序。它們的參數選項很多,這里只做簡單介紹,依舊舉例說明一下其用法: # zip all.zip *.jpg 這條命令是將所有 .jpg 的文件壓縮成一個 zip 包 # unzip all.zip 這條命令是將 all.zip 中的所有文件解壓出來 (2)對于 .rar 要在 linux 下處理 .rar 文件,需要安裝 RAR for Linux,可以從網上下載,但要記住,RAR for Linux 不是免費的;可從 http://www.rarsoft.com/download.htm 下載 RAR for Linux 3.2.0,然后安裝: # tar -xzpvf rarlinux-3.2.0.tar.gz # cd rar # make 這樣就安裝好了,安裝后就有了 rar 和 unrar 這兩個程序,rar 是壓縮程序,unrar 是解壓程序。它們的參數選項很多,這里只做簡單介紹,依舊舉例說明一下其用法: # rar a all *.jpg 這條命令是將所有 .jpg 的文件壓縮成一個 rar 包,名為 all.rar,該程序會將 .rar 擴展名將自動附加到包名后。 # unrar e all.rar 這條命令是將 all.rar 中的所有文件解壓出來 到此為至,我們已經介紹過 linux 下的 tar、gzip、gunzip、bzip2、bunzip2、compress、uncompress、zip、unzip、rar、unrar 等程式,你應該已經能夠使用它們對 .tar、.gz、.tar.gz、.tgz、.bz2、.tar.bz2、.Z、.tar.Z、.zip、.rar 這 10 種壓縮文件進行解壓了,以后應該不需要為下載了一個軟件而不知道如何在 Linux 下解開而煩惱了。而且以上方法對于 Unix 也基本有效。 本文介紹了 linux 下的壓縮程式 tar、gzip、gunzip、bzip2、bunzip2、compress、uncompress、zip、unzip、rar、unrar 等程式,以及如何使用它們對 .tar、.gz、.tar.gz、.tgz、.bz2、.tar.bz2、.Z、.tar.Z、.zip、.rar 這 10 種壓縮文件進行操作。
3.2 VSFTP 安全與效能兼備的ftp 服務器 3.2.1 VSFTP 概述 FTP,file transfer protocol,這是檔案傳輸的通訊協議,也是一般最常用來傳送檔案的方式。讀者在使用RedHat9 的時候,可能會感受到ftp server 有一些改變:第一,就是ftp server 只剩下vsftp,原有的wuftp 等都沒放入 第二,就是vsftp 從XINETD 中獨立出來,并將設定檔從/etc/vsftpd.conf 之中移到/etc/vsftpd/vsftpd.conf。 為什么做這樣的改變?可以想見的是vsftp 已有獨立運作的能力,不需要XINETD 來做更進一步的管控,并且類似sendmail、httpd、ssh、samba 等,將設定文件的放入/etc 下獨立的目錄。 FTP 分為兩類,一種為PORT FTP,也就是一般的FTP 另一類是PASVFTP,分述如下: PORT FTP 這是一般形式的FTP,首先會建立控制頻道,默認值是port 21,也就是跟port 21 建立聯機,并透過此聯機下達指令。第二,由FTP server 端會建立數據傳輸頻道,默認值為20,也就是跟port 20 建立聯機,并透過port 20 作數據的傳輸。 PASV FTP 跟PORT FTP 類似,首先會建立控制頻道,默認值是port 21,也就是跟port 21 建立聯機,并透過此聯機下達指令。第二,會由client 端做出數據傳輸的請求,包括數據傳輸port 的數字。 這兩者的差異為何?PORT FTP 當中的數據傳輸port 是由FTP server 指定,而PASV FTP 的數據傳輸port 是由FTP client 決定。通常我們使用PASV FTP,是在有防火墻的環境之下,透過client 與server 的溝通,決定數據傳輸的port。 3.2.2 范例 3.2.1. 直接啟動VSFTP 服務 這個范例是套用RedHat 的預設范例,直接啟動vsftp。 [root@relay vsftpd]# /sbin/service vsftpd start Starting vsftpd for vsftpd: OK ] 3.2.2. 更換port 提供服務:將預設的port 21 更換為2121 為了安全,或是以port 來區隔不同的ftp 服務,我們可能會將ftp port 改為21 之外的port,那么,可參考以下步驟。 Step1. 修改/etc/vsftpd/vsftpd.conf 新增底下一行 listen_port=2121 Step2. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 3.2.3. 特定使用者peter、john 不得變更目錄 使用者的預設目錄為/home/username,若是我們不希望使用者在ftp 時能夠 切換到上一層目錄/home,則可參考以下步驟。 Step1. 修改/etc/vsftpd/vsftpd.conf 將底下三行 #chroot_list_enable=YES # (default follows) #chroot_list_file=/etc/vsftpd.chroot_list 改為 chroot_list_enable=YES # (default follows) chroot_list_file=/etc/vsftpd/chroot_list Step2. 新增一個檔案: /etc/vsftpd/chroot_list 內容增加兩行: peter john Step3. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 若是peter 欲切換到根目錄以外的目錄,則會出現以下警告: ftp> cd /home 550 Failed to change directory. 3.2.4. 取消anonymous 登入 若是讀者的主機不希望使用者匿名登入,則可參考以下步驟。 Step1. 修改/etc/vsftpd/vsftpd.conf 將 anonymous_enable=YES 改為 anonymous_enable=NO Step2. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 3.2.5. 安排歡迎話語 若是我們希望使用者在登入時,能夠看到歡迎話語,可能包括對該主機的說明,或是目錄的介紹,可參考以下步驟。 首先確定在/etc/vsftpd/vsftpd.conf 當中是否有底下這一行 dirmessage_enable=YES RedHat9 的默認值是有上面這行的。 接著,在各目錄之中,新增名為.message 的檔案,再這邊假設有一個使用者test1,且此使用者的根目錄下有個目錄名為abc,那首先我們在/home/test1 之下新增.message,內容如下: Hello~ Welcome to the home directory This is for test only... 接著,在/home/test1/abc 的目錄下新增.message,內容如下: Welcome to abc's directory This is subdir... 那么,當使用者test1 登入時,會看到以下訊息: 230- Hello~ Welcome to the home directory 230- 230- This is for test only... 230- 若是切換到abc 的目錄,則會出現以下訊息: 250- Welcome to abc's directory 250- 250- This is subdir ... 3.2.6. 對于每一個聯機,以獨立的process 來運作 一般啟動vsftp 時,我們只會看到一個名為vsftpd 的process 在運作,但若是讀者希望每一個聯機,都能以獨立的process 來呈現,則可執行以下步驟。 Step1. 修改/etc/vsftpd/vsftpd.conf 新增底下一行 setproctitle_enable=YES Step2. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 使用ps -ef 的指令,可以看告不同使用者聯機的情形,如下圖所示: [root@home vsftpd]# ps -ef|grep ftp root 2090 1 0 16:41 pts/0 00:00:00 vsftpd: LISTENER nobody 2120 2090 0 17:18 ? 00:00:00 vsftpd: 192.168.10.244: connected test1 2122 2120 0 17:18 ? 00:00:00 vsftpd: 192.168.10.244/test1: IDLE nobody 2124 2090 0 17:19 ? 00:00:00 vsftpd: 192.168.10.244: connected test2 2126 2124 0 17:19 ? 00:00:00 vsftpd: 192.168.10.244/test2: IDLE root 2129 1343 0 17:20 pts/0 00:00:00 grep ftp [root@home vsftpd]# 3.2.7. 限制傳輸檔案的速度: 本機的使用者最高速度為200KBytes/s,匿名登入者所能使用的最高速度為50KBytes/s Step1. 修改/etc/vsftpd/vsftpd.conf 新增底下兩行 anon_max_rate=50000 local_max_rate=200000 Step2. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 在這邊速度的單位為Bytes/s,其中anon_max_rate 所限制的是匿名登入的 使用者,而local_max_rate 所限制的是本機的使用者。VSFTPD 對于速度的限 制,范圍大概在80%到120%之間,也就是我們限制最高速度為100KBytes/s, 但實際的速度可能在80KBytes/s 到120KBytes/s 之間,當然,若是頻寬不足 時,數值會低于此限制。 3.2.8. 針對不同的使用者限制不同的速度: 假設test1 所能使用的最高速度為250KBytes/s,test2 所能使用的最高速度為500KBytes/s。 Step1. 修改/etc/vsftpd/vsftpd.conf 新增底下一行 user_config_dir=/etc/vsftpd/userconf Step2. 新增一個目錄:/etc/vsftpd/userconf mkdir /etc/vsftpd/userconf Step3. 在/etc/vsftpd/userconf 之下新增一個名為test1 的檔案 內容增加一行: local_max_rate=250000 Step4. 在/etc/vsftpd/userconf 之下新增一個名為test2 的檔案 內容增加一行: local_max_rate=500000 Step5. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 3.2.9-1. 建置一個防火墻下的ftp server,使用PORT FTP mode: 預設的ftp port:21 以及ftp data port:20 啟動VSFTPD 之后執行以下兩行指令,只允許port 21 以及port 20 開放,其它關閉。 iptables -A INPUT -p tcp -m multiport --dport 21,20 -j ACCEPT iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset 3.2.9-2. 建置一個防火墻下的ftp server,使用PORT FTP mode: ftp port:2121 以及ftp data port:2020 Step1. 執行以下兩行指令,只允許port 2121 以及port 2020 開放,其它關閉。 iptables -A INPUT -p tcp -m multiport --dport 2121,2020 -j ACCEPT iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset Step2. 修改/etc/vsftpd/vsftpd.conf 新增底下兩行 listen_port=2121 ftp_data_port=2020 Step3. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 在這邊要注意,8、9 兩個例子中,ftp client(如cuteftp)的聯機方式不能夠選擇passive mode,否則無法建立數據的聯機。也就是讀者可以連上ftp server,但是執行ls、get 等等的指令時,便無法運作。 3.2.10. 建置一個防火墻下的ftp server,使用PASS FTP mode: ftp port:2121 以及ftp data port 從9981 到9986。 Step1. 執行以下兩行指令,只允許port 2121 以及port 9981-9990 開放,其它關閉。 iptables -A INPUT -p tcp -m multiport --dport 2121,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990 -j ACCEPT iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset Step2. 修改/etc/vsftpd/vsftpd.conf 新增底下四行 listen_port=2121 pasv_enable=YES pasv_min_port=9981 pasv_max_port=9986 Step3. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] 在這邊要注意,在10 這個例子中,ftp client(如cuteftp)的聯機方式必須選擇passive mode,否則無法建立數據的聯機。也就是讀者可以連上ftp server,但是執行ls,get 等等的指令時,便無法運作。 3.2.11. 將vsftpd 與TCP_wrapper 結合 若是讀者希望直接在/etc/hosts.allow 之中定義允許或是拒絕的來源地址,可執行以下步驟。這是簡易的防火墻設定。 Step1. 確定/etc/vsftpd/vsftpd.conf 之中tcp_wrappers 的設定為YES,如下圖所 示: tcp_wrappers=YES 這是RedHat9 的默認值,基本上不需修改。 Step2. 重新啟動vsftpd [root@home vsftpd]# /sbin/service vsftpd restart Shutting down vsftpd: OK ] Starting vsftpd for vsftpd: OK ] Step3. 設定/etc/hosts.allow,譬如提供111.22.33.4 以及10.1.1.1 到10.1.1.254 連 線,則可做下圖之設定: vsftpd : 111.22.33.4 10.1.1. : allow ALL : ALL : DENY 3.2.12. 將vsftpd 并入XINETD 若是讀者希望將vsftpd 并入XINETD 之中,也就是7.x 版的預設設定,那 么讀者可以執行以下步驟。 Step1. 修改/etc/vsftpd/vsftpd.conf 將 listen=YES 改為 listen=NO Step2. 新增一個檔案: /etc/xinetd.d/vsftpd 內容如下: service vsftpd { disable = no socket_type = stream wait = no user = root server = /usr/sbin/vsftpd port = 21 log_on_success += PID HOST DURATION log_on_failure += HOST } Step3. 重新啟動xinetd [root@home vsftpd]# /sbin/service xinetd restart Stopping xinetd: OK ] Starting xinetd: OK ] 3.2.3 設定檔說明 在范例中,有些省略的設定可以在這邊找到,譬如聯機的總數、同一個位址的聯機數、顯示檔案擁有者的名稱等等,希望讀者細讀后,可以做出最適合自己的設定。 格式 vsftpd.conf 的內容非常單純,每一行即為一項設定。若是空白行或是開頭為#的一行,將會被忽略。內容的格式只有一種,如下所示 option=value 要注意的是,等號兩邊不能加空白,不然是不正確的設定。 ===ascii 設定===================== ascii_download_enable 管控是否可用ASCII 模式下載。默認值為NO。 ascii_upload_enable 管控是否可用ASCII 模式上傳。默認值為NO。 ===個別使用者設定=================== chroot_list_enable 如果啟動這項功能,則所有的本機使用者登入均可進到根目錄之外的數據夾,除了列 在/etc/vsftpd.chroot_list 之中的使用者之外。默認值為NO。 userlist_enable 用法:YES/NO 若是啟動此功能,則會讀取/etc/vsftpd.user_list 當中的使用者名稱。此項功能可以在詢問密碼前就出現失敗訊息,而不需要檢驗密碼的程序。默認值為關閉。 userlist_deny 用法:YES/NO 這個選項只有在userlist_enable 啟動時才會被檢驗。如果將這個選項設為YES,則在/etc/vsftpd.user_list 中的使用者將無法登入 若設為NO , 則只有在 /etc/vsftpd.user_list 中的使用者才能登入。而且此項功能可以在詢問密碼前就出現錯誤訊息,而不需要檢驗密碼的程序。 user_config_dir 定義個別使用者設定文件所在的目錄,例如定義user_config_dir=/etc/vsftpd/userconf,且主機上有使用者test1,test2,那我們可以在user_config_dir 的目錄新增文件名為test1 以及test2。若是test1 登入,則會讀取user_config_dir 下的test1 這個檔案內的設定。默認值為無。 ===歡迎語設定===================== dirmessage_enable 如果啟動這個選項,使用者第一次進入一個目錄時,會檢查該目錄下是否有.message這個檔案,若是有,則會出現此檔案的內容,通常這個檔案會放置歡迎話語,或是對該目錄的說明。默認值為開啟。 banner_file 當使用者登入時,會顯示此設定所在的檔案內容,通常為歡迎話語或是說明。默認值為無。 ftpd_banner 這邊可定義歡迎話語的字符串,相較于banner_file 是檔案的形式,而ftpd_banner 是字串的格式。預設為無。 ===特殊安全設定==================== chroot_local_user 如果設定為YES,那么所有的本機的使用者都可以切換到根目錄以外的數據夾。預設值為NO。 hide_ids 如果啟動這項功能,所有檔案的擁有者與群組都為ftp,也就是使用者登入使用ls -al之類的指令,所看到的檔案擁有者跟群組均為ftp。默認值為關閉。 ls_recurse_enable 若是啟動此功能,則允許登入者使用ls -R 這個指令。默認值為NO。 write_enable 用法:YES/NO 這個選項可以控制FTP 的指令是否允許更改file system,譬如STOR、DELE、 RNFR、RNTO、MKD、RMD、APPE 以及SITE。預設是關閉。 setproctitle_enable 用法:YES/NO 啟動這項功能,vsftpd 會將所有聯機的狀況已不同的process 呈現出來,換句話說,使用ps -ef 這類的指令就可以看到聯機的狀態。默認值為關閉。 tcp_wrappers 用法:YES/NO 如果啟動,則會將vsftpd 與tcp wrapper 結合,也就是可以在/etc/hosts.allow 與/etc/hosts.deny 中定義可聯機或是拒絕的來源地址。 pam_service_name 這邊定義PAM 所使用的名稱,預設為vsftpd。 secure_chroot_dir 這個選項必須指定一個空的數據夾且任何登入者都不能有寫入的權限,當vsftpd 不需要file system 的權限時,就會將使用者限制在此數據夾中。默認值為/usr/share/empty ===紀錄文件設定===================== xferlog_enable 用法:YES/NO 如果啟動,上傳與下載的信息將被完整紀錄在底下xferlog_file 所定義的檔案中。預設為開啟。 xferlog_file 這個選項可設定紀錄文件所在的位置,默認值為/var/log/vsftpd.log。 xferlog_std_format 如果啟動,則紀錄文件將會寫為xferlog 的標準格式,如同wu-ftpd 一般。默認值為關閉。 ===逾時設定====================== accept_timeout 接受建立聯機的逾時設定,單位為秒。默認值為60。 connect_timeout 響應PORT 方式的數據聯機的逾時設定,單位為秒。默認值為60。 data_connection_timeout 建立數據聯機的逾時設定。默認值為300 秒。 idle_session_timeout 發呆的逾時設定,若是超出這時間沒有數據的傳送或是指令的輸入,則會強迫斷線,單位為秒。默認值為300。 ===速率限制====================== anon_max_rate 匿名登入所能使用的最大傳輸速度,單位為每秒多少bytes,0 表示不限速度。默認值為0。 local_max_rate 本機使用者所能使用的最大傳輸速度,單位為每秒多少bytes,0 表示不限速度。預設值為0。 ===新增檔案權限設定================== anon_umask 匿名登入者新增檔案時的umask 數值。默認值為077。 file_open_mode 上傳檔案的權限,與chmod 所使用的數值相同。默認值為0666。 local_umask 本機登入者新增檔案時的umask 數值。默認值為077。 ===port 設定====================== connect_from_port_20 用法:YES/NO 若設為YES,則強迫ftp-data 的數據傳送使用port 20。默認值為YES。 ftp_data_port 設定ftp 數據聯機所使用的port。默認值為20。 listen_port FTP server 所使用的port。默認值為21。 pasv_max_port 建立資料聯機所可以使用port 范圍的上界,0 表示任意。默認值為0。 pasv_min_port 建立資料聯機所可以使用port 范圍的下界,0 表示任意。默認值為0。 ===其它======================== anon_root 使用匿名登入時,所登入的目錄。默認值為無。 local_enable 用法:YES/NO 啟動此功能則允許本機使用者登入。默認值為YES。 local_root 本機使用者登入時,將被更換到定義的目錄下。默認值為無。 text_userdb_names 用法:YES/NO 當使用者登入后使用ls -al 之類的指令查詢該檔案的管理權時,預設會出現擁有者的UID,而不是該檔案擁有者的名稱。若是希望出現擁有者的名稱,則將此功能開啟。默認值為NO。 pasv_enable 若是設為NO,則不允許使用PASV 的模式建立數據的聯機。默認值為開啟。 ===更換檔案所有權=================== chown_uploads 用法:YES/NO 若是啟動,所有匿名上傳數據的擁有者將被更換為chown_username 當中所設定的使用者。這樣的選項對于安全及管理,是很有用的。默認值為NO。 chown_username 這里可以定義當匿名登入者上傳檔案時,該檔案的擁有者將被置換的使用者名稱。預設值為root。 ===guest 設定===================== guest_enable 用法:YES/NO 若是啟動這項功能,所有的非匿名登入者都視為guest。默認值為關閉。 guest_username 這里將定義guest 的使用者名稱。默認值為ftp。 ===anonymous 設定================== anonymous_enable 用法:YES/NO 管控使否允許匿名登入,YES 為允許匿名登入,NO 為不允許。默認值為YES。 no_anon_password 若是啟動這項功能,則使用匿名登入時,不會詢問密碼。默認值為NO。 anon_mkdir_write_enable 用法:YES/NO 如果設為YES,匿名登入者會被允許新增目錄,當然,匿名使用者必須要有對上層目錄的寫入權。默認值為NO。 anon_other_write_enable 用法:YES/NO 如果設為YES,匿名登入者會被允許更多于上傳與建立目錄之外的權限,譬如刪除或是更名。默認值為NO。 anon_upload_enable 用法:YES/NO 如果設為YES,匿名登入者會被允許上傳目錄的權限,當然,匿名使用者必須要有對上層目錄的寫入權。默認值為NO。 anon_world_readable_only 用法:YES/NO 如果設為YES,匿名登入者會被允許下載可閱讀的檔案。默認值為YES。 ftp_username 定義匿名登入的使用者名稱。默認值為ftp。 deny_email_enable 若是啟動這項功能,則必須提供一個檔案/etc/vsftpd.banner_emails,內容為email address。若是使用匿名登入,則會要求輸入email address,若輸入的email address 在此檔案內,則不允許聯機。默認值為NO。 ===Standalone 選項================== listen 用法:YES/NO 若是啟動,則vsftpd 將會以獨立運作的方式執行,若是vsftpd 獨立執行,如RedHat9的默認值,則必須啟動 若是vsftpd 包含在xinetd 之中,則必須關閉此功能,如RedHat8。在RedHat9 的默認值為YES。 listen_address 若是vsftpd 使用standalone 的模式,可使用這個參數定義使用哪個IP address 提供這項服務,若是主機上只有定義一個IP address,則此選項不需使用,若是有多個IP address,可定義在哪個IP address 上提供ftp 服務。若是不設定,則所有的IP address均會提供此服務。默認值為無。 max_clients 若是vsftpd 使用standalone 的模式,可使用這個參數定義最大的總聯機數。超過這個數目將會拒絕聯機,0 表示不限。默認值為0。 max_per_ip 若是vsftpd 使用standalone 的模式,可使用這個參數定義每個ip address 所可以聯機的數目。超過這個數目將會拒絕聯機,0 表示不限。默認值為0。 ============================= 3.2.4 FTP 數字代碼的意義 110 重新啟動標記應答。 120 服務在多久時間內ready。 125 數據鏈路埠開啟,準備傳送。 150 文件狀態正常,開啟數據連接端口。 200 命令執行成功。 202 命令執行失敗。 211 系統狀態或是系統求助響應。 212 目錄的狀態。 213 文件的狀態。 214 求助的訊息。 215 名稱系統類型。 220 新的聯機服務ready。 221 服務的控制連接埠關閉,可以注銷。 225 數據連結開啟,但無傳輸動作。 226 關閉數據連接端口,請求的文件操作成功。 227 進入passive mode。 230 使用者登入。 250 請求的文件操作完成。 257 顯示目前的路徑名稱。 331 用戶名稱正確,需要密碼。 332 登入時需要賬號信息。 350 請求的操作需要進一部的命令。 421 無法提供服務,關閉控制連結。 425 無法開啟數據鏈路。 426 關閉聯機,終止傳輸。 450 請求的操作未執行。 451 命令終止:有本地的錯誤。 452 未執行命令:磁盤空間不足。 500 格式錯誤,無法識別命令。 501 參數語法錯誤。 502 命令執行失敗。 503 命令順序錯誤。 504 命令所接的參數不正確。 530 未登入。 532 儲存文件需要賬戶登入。 550 未執行請求的操作。 551 請求的命令終止,類型未知。 552 請求的文件終止,儲存位溢出。 553 未執行請求的的命令,名稱不正確。
1. 什么是grub grub 是一個多重啟動管理器。grub是GRand Unified Bootloader的縮寫,它可以在多個操作系統共存時選擇引導哪個系統。它可以引導的操作系包括linux,FreeBSD,Solaris,NetBSD,BeOSi,OS/2,Windows95/98,Windows NT,Windows2000。它可以載入操作系統的內核和初始化操作系統(如Linux,FreeBSD),或者把引導權交給操作系統(如Windows 98)來完成引導。 2. grub的特點 grub可以代替lilo來完成對Linux的引導,特別適用于linux與其它操作系統共存情況,與lilo相比,它有以下特點: 支持大硬盤 現在大多數Linux發行版本的lilo都有同樣的一個問題:根分區(/boot分區)不能分在超過1024柱面的地方,一般是在8.4G左右的地方,否則lilo不能安裝,或者安裝后不能正確引導系統。而grub就不會出現這種情況,只要安裝時你的大硬盤是在LBA模式下,grub就可以引導根分區在8G以外的操作系統。 支持開機畫面 grub支持在引導開機的同時顯示一個開機畫面。對于玩家來說,這樣可以制作自己的個性化開機畫面;對于PC廠商,這樣可以在開機時顯示電腦的一些信息和廠商的標志等。grub支持640x480,800x600,1024x768各種模式的開機畫面,而且可以自動偵測選擇最佳模式,與Windows那320x400的開機畫面不可同日而語。 兩種執行模式 grub不但可以通過配置文件進行例行的引導,還可以在選擇引導前動態改變引導時的參數,還可以動態加載各種設備。例如你在Linux下編譯了一個新的核心,但不能確定它能不能工作,你就可以在引導時動態改變grub的參數,嘗試裝載這個新的核心進行使用。Grub的命令行有非常強大的功能,而且支持如bash或doskey一樣的歷史功能,你可以用上下鍵來尋找以前的命令。 菜單式選擇 在lilo下,你需要手工輸入操作系統的名字來引導不同的操作系統。而grub使用一個菜單來選擇不同的系統進行引導。你還可以自己配置各種參數,如延遲時間,默認操作系統等。 分區位置改變后不必重新配置 lilo是通過讀取硬盤上的絕對扇區來裝入操作系統,因此每次分區改變都必須重新配置lilo,例如你用PQ magic調整了分區的大小,那lilo在你重新配置好之前就不能引導這個分區的操作系統了。而grub是通過文件系統直接把核心讀取到內存,因此只要操作系統核心的路徑沒有改變,grub就可以引導系統。 除此之外,Grub還有許多非常強大的功能。例如支持多種外部設備,動態裝載操作系統內核,甚至可以通過網絡裝載操作系統核心。Grub支持多種文件系統,支持多種可執行文件格式,支持自動解壓,可以引導不支持多重引導的操作系統等。 3. grub的使用 安裝grub 如果已經安裝了藍點Linux2.0則grub是默認安裝的。要把grub重新安裝到主引導扇區上,只需要簡單打入makebootable命令就可以了。 制作grub啟動盤 首先確定grub已經安裝,然后進入grub的目錄,鍵入: #cd /boot/grub 放入一張軟盤,然后敲入命令: #dd if=stage1 of=/dev/fd0 bs=512 count=1 #dd if=/stage2 of=/dev/fd0 bs512 seek=1 這樣就可以做好一張啟動盤了。 開機 安裝了grub開機后會出現一個菜單,列出所有的啟動選項。如果設置了啟動畫面則會顯示啟動畫面,按Esc鍵則可以取消啟動畫面顯示菜單選項。藍點Linux所帶的grub的命令提示是全中文的,在菜單下面詳細列出如按e是編輯啟動命令,按c是使用命令行等。用上下鍵可以選擇菜單項,按回車啟動所選項。按e鍵可以編輯所選項的啟動命令,你可以用這個功能臨時改變你的系統的啟動參數,參見配置grub一節。按c鍵則進入命令行模式。 在命令行模式下可以打入命令直接執行,例如你可以敲入poweroff關閉計算機。按Tab鍵可以列出所有支持的命令。藍點Linux已經把grub漢化了,其中一部分命令敲入名字后會給出中文提示,顯示命令的用法和參數。 4. 配置grub grub啟動時會在/boot/grub/中尋找一個名字為menu.lst的配置文件,如果找不到此文件則不進入菜單模式而直接進入命令行模式。 menu.lst 是一個文本文件,你可以用任何一個文本編輯器來打開它。每一行代表一個配置命令,如果一行的第一個字符為井號"#"則這一行為注釋,你可以簡單地用增加或減少注釋行來改變配置。 編輯menu.lst,一般會有以下各行 timeout second 設定在second秒之后引導默認的操作系統。 藍點Linux默認是timeout 5,就是5秒沒有其他指令就引導系統,如果設成-1,則grub會一直等待直到用戶選擇一個選項為止。 default num 默認啟動第num+1行選項,也就說default=0則默認啟動菜單第一行的操作系統,default=1則啟動第2行的系統,如此類推。 splash pathname/filename 指出開機畫面的文件所存放的路徑和文件名,如 splash /boot/logo/800x600x8.img 是指用在/boot/logo路徑下的800x600.img文件作為開機畫面 title OSname title 后面的字符就是你在菜單項上所看見的選項,你可以寫上操作系統的名字和描述,如用 title BluePoint Linux, Single Mode 代表這一選項是引導藍點Linux的單用戶模式。 下面結合兩個系統引導描述來解釋幾個引導選項的意義 title BluePoint Linux, Default Mode root (hd0,1) kernel /boot/vmlinuz vga=auto root=/dev/hda2 hd0是指第一個硬盤(主硬盤) (hd0,1)是指第一個硬盤的第二個分區。 kernel /boot/vmlinuz 是指出Linux核心的路徑在/boot/vmlinuz中。vga=auto 是設定顯示模式,root=/dev/hda2是指把第一個硬盤的第二個分區作為根掛載點("/")。 title Microsoft Windows root (hd1,0) chainloader (hd1,0)+1 root (hd1,0)這是指第二個硬盤(從硬盤)上第一個分區 chainloader (hd1,0)+1 裝入一個扇區的數據然后把引導權交給它。 5. 從軟盤啟動grub 制作啟動盤后可以用軟盤啟動引導硬盤上的操作系統 插入制作好的啟動軟盤,進入BIOS設定軟盤啟動。軟盤啟動成功后就會進入grub的命令行模式 grub> 要啟動一個操作系統,首先指定引導哪個分區上的系統,例如要引導指第一個硬盤上的第一個分區的操作系統,先鍵入 grub>root (hd0,0) 接著如果要啟動的是Windows系統,鍵入 grub>chainloader (hd0,0)+1 注意(hd0,0)要隨著硬盤和分區的不同而改變數字。 如果要引導Linux或其他系統,應鍵入 grub>kernel (hd0,0)/boot/vmlinuz root=/dev/hda1 注意hda1參數也要隨著硬盤和分區的不同而改變,如從第二個硬盤的第一個分區引導則用hdb1。 最后敲入boot就可以啟動系統了。 在任何時候不能確定命令或者命令的參數都可以按Tab獲得相關的幫助。用上下鍵可以獲得命令的歷史記錄。 其實這些命令就是menu.lst的啟動描述,您也可以根據那些描述來自己鍵入啟動命令,最后敲入boot就可以引導系統了。
|
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
27 | 28 | 29 | 30 | 31 | 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 | 1 | 2 | 3 | 4 | 5 | 6 |
|
導航
統計
常用鏈接
留言簿(1)
隨筆分類(32)
隨筆檔案(33)
搜索
最新評論

閱讀排行榜
評論排行榜
|
|